diff options
Diffstat (limited to 'lib/sugar-web/graphics/palette.js')
-rw-r--r-- | lib/sugar-web/graphics/palette.js | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/lib/sugar-web/graphics/palette.js b/lib/sugar-web/graphics/palette.js new file mode 100644 index 0000000..9a194a1 --- /dev/null +++ b/lib/sugar-web/graphics/palette.js @@ -0,0 +1,179 @@ +define(function () { + var palettesGroup = []; + + function getOffset(elem) { + // Ugly hack to consider the palette margin. + var style = elem.currentStyle || window.getComputedStyle(elem, ''); + + // Remove 'px' from the strings. + var x = -2 * style.marginLeft.slice(0, -2); + var y = -1 * style.marginTop.slice(0, -2); + + var rect = elem.getBoundingClientRect(); + x += rect.left; + y += rect.top; + return { + top: y, + left: x, + width: rect.width, + height: rect.height + }; + } + + var palette = {}; + + palette.Palette = function (invoker, primaryText) { + this.invoker = invoker; + if (this.invoker.classList.contains("toolbutton")) { + this.invoker.classList.add("invoker"); + } + this.primaryText = primaryText; + var paletteElem; + var wrapperElem; + var headerElem; + var headerSeparatorElem; + var containerElem; + var that = this; + palettesGroup.push(this); + + invoker.addEventListener('click', function (event) { + if (!that.invoker.classList.contains("toolbutton")) { + updatePosition(event.x, event.y); + } + that.toggle(); + }); + + function updatePosition(clickX, clickY) { + var paletteX; + var paletteY; + + if (typeof (clickX) !== 'undefined' && + typeof (clickY) !== 'undefined') { + paletteX = clickX; + paletteY = clickY; + } else { + var invokerOffset = getOffset(that.invoker); + paletteX = invokerOffset.left; + paletteY = invokerOffset.top; + } + + paletteElem.style.left = paletteX + "px"; + paletteElem.style.top = paletteY + "px"; + } + + // A palette element can have a header, content, one or both. + + function createPaletteElement() { + if (paletteElem !== undefined) { + return; + } + paletteElem = document.createElement('div'); + paletteElem.className = "palette"; + paletteElem.style.visibility = "hidden"; + document.body.appendChild(paletteElem); + + if (that.invoker.classList.contains("toolbutton")) { + invokerElem = document.createElement('div'); + invokerElem.className = "palette-invoker"; + var style = that.invoker.currentStyle || + window.getComputedStyle(that.invoker, ''); + invokerElem.style.backgroundImage = style.backgroundImage; + + invokerElem.addEventListener('click', function (e) { + that.toggle(); + }); + + paletteElem.appendChild(invokerElem); + + } + + wrapperElem = document.createElement('div'); + wrapperElem.className = "wrapper"; + paletteElem.appendChild(wrapperElem); + + if (that.primaryText !== undefined) { + headerElem = document.createElement('div'); + headerElem.className = "header"; + headerElem.innerText = that.primaryText; + wrapperElem.appendChild(headerElem); + } + + headerSeparatorElem = document.createElement('hr'); + headerSeparatorElem.className = "header-separator"; + headerSeparatorElem.style.display = "none"; + wrapperElem.appendChild(headerSeparatorElem); + + containerElem = document.createElement('div'); + containerElem.className = "container"; + wrapperElem.appendChild(containerElem); + + updatePosition(); + } + + this.getPalette = function () { + if (paletteElem === undefined) { + createPaletteElement(); + } + return paletteElem; + }; + + this.setContent = function (elementsList) { + if (paletteElem === undefined) { + createPaletteElement(); + } + + (function removePreviousContent() { + for (var i = 0; i < containerElem.children.length; i++) { + var child = containerElem.children[i]; + containerElem.removeChild(child); + } + }()); + + (function addNewContent() { + for (var i = 0; i < elementsList.length; i++) { + var child = elementsList[i]; + containerElem.appendChild(child); + } + }()); + + // The header separator will be visible only if there are + // both, header and content. + if (elementsList.length > 0 && this.primaryText !== undefined) { + headerSeparatorElem.style.display = "block"; + } else { + headerSeparatorElem.style.display = "none"; + } + }; + + this.isDown = function () { + return paletteElem === undefined || + paletteElem.style.visibility == "hidden"; + }; + + }; + + palette.Palette.prototype.popUp = function () { + for (var i = 0; i < palettesGroup.length; i++) { + otherPalette = palettesGroup[i]; + if (otherPalette != this) { + otherPalette.popDown(); + } + } + this.getPalette().style.visibility = "visible"; + }; + + palette.Palette.prototype.popDown = function () { + this.getPalette().style.visibility = "hidden"; + }; + + palette.Palette.prototype.toggle = function () { + if (this.isDown()) { + this.popUp(); + } else { + this.popDown(); + } + }; + + return palette; + +}); |