www/include/scripts/joust-2.js

Code
Comments
Other
Rev Date Author Line
6363 29 Nov 13 nicklas 1 /* $Id$
6363 29 Nov 13 nicklas 2   ------------------------------------------------------------------
6363 29 Nov 13 nicklas 3   Copyright (C) 2012 Nicklas Nordborg
6363 29 Nov 13 nicklas 4
6363 29 Nov 13 nicklas 5   This file is part of BASE - BioArray Software Environment.
6363 29 Nov 13 nicklas 6   Available at http://base.thep.lu.se/
6363 29 Nov 13 nicklas 7
6363 29 Nov 13 nicklas 8   BASE is free software; you can redistribute it and/or
6363 29 Nov 13 nicklas 9   modify it under the terms of the GNU General Public License
6363 29 Nov 13 nicklas 10   as published by the Free Software Foundation; either version 3
6363 29 Nov 13 nicklas 11   of the License, or (at your option) any later version.
6363 29 Nov 13 nicklas 12
6363 29 Nov 13 nicklas 13   BASE is distributed in the hope that it will be useful,
6363 29 Nov 13 nicklas 14   but WITHOUT ANY WARRANTY; without even the implied warranty of
6363 29 Nov 13 nicklas 15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6363 29 Nov 13 nicklas 16   GNU General Public License for more details.
6363 29 Nov 13 nicklas 17
6363 29 Nov 13 nicklas 18   You should have received a copy of the GNU General Public License
6363 29 Nov 13 nicklas 19   along with BASE. If not, see <http://www.gnu.org/licenses/>.
6363 29 Nov 13 nicklas 20   ------------------------------------------------------------------
6363 29 Nov 13 nicklas 21
6363 29 Nov 13 nicklas 22   JavaScript functions for the Joust2 tree outline.
6363 29 Nov 13 nicklas 23
6363 29 Nov 13 nicklas 24   @author Nicklas
6363 29 Nov 13 nicklas 25   @since 3.3
6363 29 Nov 13 nicklas 26 */
7419 03 Nov 17 nicklas 27 'use strict';
6363 29 Nov 13 nicklas 28
6363 29 Nov 13 nicklas 29 var Joust2 = function()
6363 29 Nov 13 nicklas 30 {
6363 29 Nov 13 nicklas 31   var joust = {};
6363 29 Nov 13 nicklas 32   var internal = {};
6363 29 Nov 13 nicklas 33
6380 16 Dec 13 nicklas 34   /**
6380 16 Dec 13 nicklas 35     Initialize and draw the Joust tree on
6380 16 Dec 13 nicklas 36     the given element. The tree definitions must
6380 16 Dec 13 nicklas 37     be stored as a JSON object in 'data-joust-tree' 
6380 16 Dec 13 nicklas 38     attribute.
6380 16 Dec 13 nicklas 39   */
6380 16 Dec 13 nicklas 40   joust.draw = function(element)
6380 16 Dec 13 nicklas 41   {
6380 16 Dec 13 nicklas 42     element = Doc.element(element);
6380 16 Dec 13 nicklas 43     
6380 16 Dec 13 nicklas 44     var tree = Data.json(element, 'joust-tree');
6380 16 Dec 13 nicklas 45     if (!tree) return;
6380 16 Dec 13 nicklas 46     
6380 16 Dec 13 nicklas 47     var last = tree.length-1;
6380 16 Dec 13 nicklas 48     for (var itemNo = 0; itemNo < tree.length; itemNo++)
6380 16 Dec 13 nicklas 49     {
6380 16 Dec 13 nicklas 50       var menuItem = tree[itemNo];
6380 16 Dec 13 nicklas 51       
6380 16 Dec 13 nicklas 52       // Genereate <div> tag for each menuItem
6382 17 Dec 13 nicklas 53       var menuElement = internal.toElement(element, menuItem, '', itemNo==0, itemNo==last);
6388 07 Jan 14 nicklas 54       var appendElement = menuElement.parentNode == null;
6388 07 Jan 14 nicklas 55       if (appendElement) element.appendChild(menuElement);
6382 17 Dec 13 nicklas 56       
6380 16 Dec 13 nicklas 57       // Generate child elements with padding
6380 16 Dec 13 nicklas 58       if (menuItem.children)
6380 16 Dec 13 nicklas 59       {
6382 17 Dec 13 nicklas 60         var pad = internal.padHtml(menuItem);
6388 07 Jan 14 nicklas 61         var childDiv = internal.addChildren(menuItem, pad);
6388 07 Jan 14 nicklas 62         if (appendElement) element.appendChild(childDiv);
6380 16 Dec 13 nicklas 63       }
6380 16 Dec 13 nicklas 64     }
6380 16 Dec 13 nicklas 65   }
6380 16 Dec 13 nicklas 66   
6381 17 Dec 13 nicklas 67   /**
6382 17 Dec 13 nicklas 68     Add child items to a menu element. It is assumed that
6382 17 Dec 13 nicklas 69     this method is called on a menu element that currently
6382 17 Dec 13 nicklas 70     has no children.
6382 17 Dec 13 nicklas 71    */
6382 17 Dec 13 nicklas 72   joust.addChildren = function(menuElement, children)
6382 17 Dec 13 nicklas 73   {
6382 17 Dec 13 nicklas 74     menuElement = Doc.element(menuElement);
6382 17 Dec 13 nicklas 75     
6382 17 Dec 13 nicklas 76     var menuItem = menuElement.item;
6382 17 Dec 13 nicklas 77     menuItem.children = children;
6382 17 Dec 13 nicklas 78     menuItem.isLazy = false;
6382 17 Dec 13 nicklas 79     
6382 17 Dec 13 nicklas 80     var pad = internal.padHtml(menuItem);
6382 17 Dec 13 nicklas 81     var childContainer = internal.addChildren(menuItem, menuItem.pad+pad);
6382 17 Dec 13 nicklas 82     menuElement.parentNode.insertBefore(childContainer, menuElement.nextSibling);
7983 22 Jun 21 nicklas 83     return childContainer;
6382 17 Dec 13 nicklas 84   }
6382 17 Dec 13 nicklas 85   
6382 17 Dec 13 nicklas 86   /**
6381 17 Dec 13 nicklas 87     Toggle the open/closed status of the given menu
6381 17 Dec 13 nicklas 88     element. Sends a 'joust-expand' event to the
6381 17 Dec 13 nicklas 89     node unless noEvent option is set.
6381 17 Dec 13 nicklas 90   */
6381 17 Dec 13 nicklas 91   joust.toggle = function(menuElement, noEvent)
6380 16 Dec 13 nicklas 92   {
6380 16 Dec 13 nicklas 93     menuElement = Doc.element(menuElement);
6380 16 Dec 13 nicklas 94     var menuItem = menuElement.item;
6380 16 Dec 13 nicklas 95     
6382 17 Dec 13 nicklas 96     if (!menuItem.isOpen && menuItem.isLazy)
6380 16 Dec 13 nicklas 97     {
6382 17 Dec 13 nicklas 98       Events.sendCustomEvent(menuElement, 'joust-lazy-init', {});
6382 17 Dec 13 nicklas 99       return;
6380 16 Dec 13 nicklas 100     }
6380 16 Dec 13 nicklas 101     
6382 17 Dec 13 nicklas 102     menuItem.isOpen = menuItem.isOpen ? 0 : 1;
6388 07 Jan 14 nicklas 103     var childContainer = Doc.element(menuItem.id+'-children');
6388 07 Jan 14 nicklas 104     if (childContainer)
6388 07 Jan 14 nicklas 105     {
6388 07 Jan 14 nicklas 106       Doc.addOrRemoveClass(childContainer, 'closed', !menuItem.isOpen);
6388 07 Jan 14 nicklas 107     }
6382 17 Dec 13 nicklas 108     joust.updateIconsAndText(menuElement);
6380 16 Dec 13 nicklas 109     
6381 17 Dec 13 nicklas 110     if (!noEvent)
6381 17 Dec 13 nicklas 111     {
6381 17 Dec 13 nicklas 112       Events.sendCustomEvent(menuElement, 'joust-expand', {});
6381 17 Dec 13 nicklas 113     }
6380 16 Dec 13 nicklas 114   }
6380 16 Dec 13 nicklas 115   
6381 17 Dec 13 nicklas 116   /**
6381 17 Dec 13 nicklas 117     Select the given menu element in the joust tree.
6381 17 Dec 13 nicklas 118     Sends a 'joust-select' event to the selected node
6381 17 Dec 13 nicklas 119     unless noEvent option is set.
6381 17 Dec 13 nicklas 120    */
6381 17 Dec 13 nicklas 121   joust.select = function(menuElement, noEvent)
6380 16 Dec 13 nicklas 122   {
6380 16 Dec 13 nicklas 123     menuElement = Doc.element(menuElement);
6380 16 Dec 13 nicklas 124     var menuItem = menuElement.item;
6380 16 Dec 13 nicklas 125     var tree = menuItem.tree;
6380 16 Dec 13 nicklas 126
6382 17 Dec 13 nicklas 127     // De-select the current selected item
6380 16 Dec 13 nicklas 128     if (tree.selectedItem)
6380 16 Dec 13 nicklas 129     {
6380 16 Dec 13 nicklas 130       tree.selectedItem.isSelected = false;
6380 16 Dec 13 nicklas 131       joust.updateIconsAndText(tree.selectedItem.id);
6380 16 Dec 13 nicklas 132     }
6380 16 Dec 13 nicklas 133     
6382 17 Dec 13 nicklas 134     // Make the given item the selected item
6380 16 Dec 13 nicklas 135     tree.selectedItem = menuItem;
6380 16 Dec 13 nicklas 136     menuItem.isSelected = true;
6380 16 Dec 13 nicklas 137     joust.updateIconsAndText(menuElement);
6380 16 Dec 13 nicklas 138     
6382 17 Dec 13 nicklas 139     // Ensure parent path is open
6382 17 Dec 13 nicklas 140     var parentItem = menuItem.parent;
6382 17 Dec 13 nicklas 141     while (parentItem != null)
6382 17 Dec 13 nicklas 142     {
6382 17 Dec 13 nicklas 143       if (!parentItem.isOpen)
6382 17 Dec 13 nicklas 144       {
6382 17 Dec 13 nicklas 145         parentItem.isOpen = 1;
6382 17 Dec 13 nicklas 146         Doc.removeClass(parentItem.id+'-children', 'closed');
6382 17 Dec 13 nicklas 147         joust.updateIconsAndText(parentItem.id);
6382 17 Dec 13 nicklas 148       }
6382 17 Dec 13 nicklas 149       parentItem = parentItem.parent;
6382 17 Dec 13 nicklas 150     }
6382 17 Dec 13 nicklas 151     
6382 17 Dec 13 nicklas 152     // Make sure the selected menu entry is visible, otherwise try to scroll the main <div>
6382 17 Dec 13 nicklas 153     if (menuElement.offsetTop > tree.scrollTop + tree.offsetHeight || menuElement.offsetTop < tree.scrollTop)
6382 17 Dec 13 nicklas 154     {
6382 17 Dec 13 nicklas 155       tree.scrollTop = menuElement.offsetTop - 40;
6382 17 Dec 13 nicklas 156     }
6382 17 Dec 13 nicklas 157     
6382 17 Dec 13 nicklas 158     // Send 'joust-select' event
6381 17 Dec 13 nicklas 159     if (!noEvent)
6381 17 Dec 13 nicklas 160     {
6381 17 Dec 13 nicklas 161       Events.sendCustomEvent(menuElement, 'joust-select', {});
6381 17 Dec 13 nicklas 162     }
6380 16 Dec 13 nicklas 163   }
6380 16 Dec 13 nicklas 164   
6380 16 Dec 13 nicklas 165   /**
6380 16 Dec 13 nicklas 166     Re-draw icons based on the current state of the menu item
6380 16 Dec 13 nicklas 167     represented by the element.
6380 16 Dec 13 nicklas 168   */
6380 16 Dec 13 nicklas 169   joust.updateIconsAndText = function(menuElement)
6380 16 Dec 13 nicklas 170   {
6380 16 Dec 13 nicklas 171     menuElement = Doc.element(menuElement);
6380 16 Dec 13 nicklas 172     var menuItem = menuElement.item;
6380 16 Dec 13 nicklas 173
6380 16 Dec 13 nicklas 174     var outlineIcon = internal.outlineIcon(menuItem);
6382 17 Dec 13 nicklas 175     if (outlineIcon)
6382 17 Dec 13 nicklas 176     {
6382 17 Dec 13 nicklas 177       Doc.element(menuItem.id+'-outline').src = outlineIcon.src;
6382 17 Dec 13 nicklas 178     }
6380 16 Dec 13 nicklas 179     
6380 16 Dec 13 nicklas 180     var docIcon = internal.docIcon(menuItem);
6382 17 Dec 13 nicklas 181     if (docIcon)
6382 17 Dec 13 nicklas 182     {
6382 17 Dec 13 nicklas 183       Doc.element(menuItem.id+'-icon').src = docIcon.src;
6382 17 Dec 13 nicklas 184     }
6382 17 Dec 13 nicklas 185     
6380 16 Dec 13 nicklas 186     Doc.addOrRemoveClass(menuElement, 'selected', menuItem.isSelected);
6380 16 Dec 13 nicklas 187   }
6380 16 Dec 13 nicklas 188   
6381 17 Dec 13 nicklas 189   /**
6381 17 Dec 13 nicklas 190     Event handler for open/close of child items.
6381 17 Dec 13 nicklas 191    */
6381 17 Dec 13 nicklas 192   internal.toggle = function(event)
6381 17 Dec 13 nicklas 193   {
6381 17 Dec 13 nicklas 194     event.cancelBubble = true;
6381 17 Dec 13 nicklas 195     joust.toggle(event.currentTarget.parentNode);
6381 17 Dec 13 nicklas 196   }
6380 16 Dec 13 nicklas 197   
6381 17 Dec 13 nicklas 198   /**
6381 17 Dec 13 nicklas 199     Event handler for clicking on a menu item.
6381 17 Dec 13 nicklas 200   */
6380 16 Dec 13 nicklas 201   internal.select = function(event)
6380 16 Dec 13 nicklas 202   {
6380 16 Dec 13 nicklas 203     event.cancelBubble = true;
6380 16 Dec 13 nicklas 204     joust.select(event.currentTarget);
6380 16 Dec 13 nicklas 205   }
6380 16 Dec 13 nicklas 206   
6382 17 Dec 13 nicklas 207   internal.addChildren = function(menuItem, pad)
6380 16 Dec 13 nicklas 208   {
6380 16 Dec 13 nicklas 209     // Create child <div> container
6386 18 Dec 13 nicklas 210     var childElements = internal.makeDiv(menuItem.id+'-children', 'children ' + (menuItem.isOpen ? 'open' : 'closed'));
7347 28 Apr 17 nicklas 211     if (menuItem.className) childElements.className += ' ' + menuItem.className;
6382 17 Dec 13 nicklas 212   
6382 17 Dec 13 nicklas 213     var tree = menuItem.tree;
6380 16 Dec 13 nicklas 214     var children = menuItem.children;
6380 16 Dec 13 nicklas 215     var last = children.length-1;
6380 16 Dec 13 nicklas 216     
6380 16 Dec 13 nicklas 217     for (var childNo = 0; childNo < children.length; childNo++)
6380 16 Dec 13 nicklas 218     {
6380 16 Dec 13 nicklas 219       // Create each child element
6380 16 Dec 13 nicklas 220       var child = children[childNo];
6382 17 Dec 13 nicklas 221       child.parent = menuItem;
6388 07 Jan 14 nicklas 222       var childElement = internal.toElement(tree, child, pad, false, childNo==last);
6388 07 Jan 14 nicklas 223       var appendElement = childElement.parentNode == null;
6388 07 Jan 14 nicklas 224       if (appendElement) childElements.appendChild(childElement);
6380 16 Dec 13 nicklas 225       
6380 16 Dec 13 nicklas 226       // Recursive call to create children of the child
6380 16 Dec 13 nicklas 227       if (child.children)
6380 16 Dec 13 nicklas 228       {
6382 17 Dec 13 nicklas 229         var childPad = internal.padHtml(child);
6388 07 Jan 14 nicklas 230         var childDiv = internal.addChildren(child, pad+childPad);
6388 07 Jan 14 nicklas 231         if (appendElement) childElements.appendChild(childDiv);
6380 16 Dec 13 nicklas 232       }
6380 16 Dec 13 nicklas 233     }
6380 16 Dec 13 nicklas 234     return childElements;
6380 16 Dec 13 nicklas 235   }
6380 16 Dec 13 nicklas 236   
6380 16 Dec 13 nicklas 237   /**
6380 16 Dec 13 nicklas 238     Create a DOM element for the given menuItem definition.
6380 16 Dec 13 nicklas 239   */
6382 17 Dec 13 nicklas 240   internal.toElement = function(tree, menuItem, pad, first, last)
6380 16 Dec 13 nicklas 241   {
6380 16 Dec 13 nicklas 242     // Remember some settings
6382 17 Dec 13 nicklas 243     menuItem.pad = pad;
6380 16 Dec 13 nicklas 244     menuItem.isFirst = first;
6380 16 Dec 13 nicklas 245     menuItem.isLast = last;
6380 16 Dec 13 nicklas 246     menuItem.tree = tree;
6380 16 Dec 13 nicklas 247     menuItem.isSelected = false;
6380 16 Dec 13 nicklas 248     
6382 17 Dec 13 nicklas 249     // Create main menu <div> container
6613 21 Nov 14 nicklas 250     var menuElement = internal.makeDiv(menuItem.id, 'joustitem', pad);
6382 17 Dec 13 nicklas 251     menuElement.item = menuItem;
6385 18 Dec 13 nicklas 252     if (menuItem.className) menuElement.className += ' ' + menuItem.className;
6382 17 Dec 13 nicklas 253     menuElement.addEventListener('click', internal.select, false);
6382 17 Dec 13 nicklas 254     
6380 16 Dec 13 nicklas 255     // Outline icon
6380 16 Dec 13 nicklas 256     var outlineIcon = internal.outlineIcon(menuItem);
6382 17 Dec 13 nicklas 257     if (outlineIcon)
6382 17 Dec 13 nicklas 258     {
6382 17 Dec 13 nicklas 259       var outlineTag = outlineIcon.toHTML(menuItem.id+'-outline');
6382 17 Dec 13 nicklas 260       var outline = internal.makeDiv(null, 'outline pad ' + (!last && !first ? 'line' : 'blank'), outlineTag);
6382 17 Dec 13 nicklas 261       outline.addEventListener('click', internal.toggle, false);
6382 17 Dec 13 nicklas 262       menuElement.appendChild(outline);
6382 17 Dec 13 nicklas 263     }
6380 16 Dec 13 nicklas 264     
6380 16 Dec 13 nicklas 265     // Document icon
6380 16 Dec 13 nicklas 266     var docIcon = internal.docIcon(menuItem);
6382 17 Dec 13 nicklas 267     if (docIcon)
6382 17 Dec 13 nicklas 268     {
6382 17 Dec 13 nicklas 269       var iconTag = docIcon.toHTML(menuItem.id+'-icon');
6382 17 Dec 13 nicklas 270       var icon = internal.makeDiv(null, 'icon', iconTag);
6382 17 Dec 13 nicklas 271       menuElement.appendChild(icon);
6382 17 Dec 13 nicklas 272     }
6380 16 Dec 13 nicklas 273     
6380 16 Dec 13 nicklas 274     // Menu text
6613 21 Nov 14 nicklas 275     var text = internal.makeDiv(menuItem.id+'-text', 'text interactable', menuItem.text);
6382 17 Dec 13 nicklas 276     if (menuItem.tooltip) text.title = menuItem.tooltip;
6380 16 Dec 13 nicklas 277     menuElement.appendChild(text);
6380 16 Dec 13 nicklas 278     return menuElement;
6380 16 Dec 13 nicklas 279   }
6380 16 Dec 13 nicklas 280   
6380 16 Dec 13 nicklas 281   /**
6380 16 Dec 13 nicklas 282     Get the outline icon that should be used for the menuItem
6380 16 Dec 13 nicklas 283     in it's current state (eg. open/closed).
6380 16 Dec 13 nicklas 284    */
6380 16 Dec 13 nicklas 285   internal.outlineIcon = function(menuItem)
6380 16 Dec 13 nicklas 286   {
6382 17 Dec 13 nicklas 287     if (menuItem.noOutlineIcon == true) return null;
6380 16 Dec 13 nicklas 288     var name = '';
6382 17 Dec 13 nicklas 289     if (menuItem.isLazy)
6380 16 Dec 13 nicklas 290     {
6380 16 Dec 13 nicklas 291       name += 'Lazy';
6380 16 Dec 13 nicklas 292     }
6380 16 Dec 13 nicklas 293     else if (menuItem.children && menuItem.children.length)
6380 16 Dec 13 nicklas 294     {
6380 16 Dec 13 nicklas 295       name += menuItem.isOpen ? 'Minus' : 'Plus';
6380 16 Dec 13 nicklas 296     }
6380 16 Dec 13 nicklas 297     else
6380 16 Dec 13 nicklas 298     {
6380 16 Dec 13 nicklas 299       name += 'Join';
6380 16 Dec 13 nicklas 300     }
6380 16 Dec 13 nicklas 301     
6380 16 Dec 13 nicklas 302     if (menuItem.isLast && !menuItem.isFirst)
6380 16 Dec 13 nicklas 303     {
6380 16 Dec 13 nicklas 304       name += 'Bottom';
6380 16 Dec 13 nicklas 305     }
6380 16 Dec 13 nicklas 306     if (menuItem.isFirst && !menuItem.isLast)
6380 16 Dec 13 nicklas 307     {
6380 16 Dec 13 nicklas 308       name += 'Top';
6380 16 Dec 13 nicklas 309     }
6380 16 Dec 13 nicklas 310     return IconStore.getIcon(name);
6380 16 Dec 13 nicklas 311   }
6380 16 Dec 13 nicklas 312   
6380 16 Dec 13 nicklas 313   internal.docIcon = function(menuItem)
6380 16 Dec 13 nicklas 314   {
6380 16 Dec 13 nicklas 315     return IconStore.getIconFromSet(menuItem.icon, menuItem.isOpen, menuItem.isSelected);
6380 16 Dec 13 nicklas 316   }
6380 16 Dec 13 nicklas 317   
6382 17 Dec 13 nicklas 318   internal.padHtml = function(menuItem)
6382 17 Dec 13 nicklas 319   {
6382 17 Dec 13 nicklas 320     if (menuItem.noOutlineIcon == true) return '';
6382 17 Dec 13 nicklas 321     return '<div class="pad '+(menuItem.isLast ? 'blank' : 'line')+'">&nbsp;</div>'
6382 17 Dec 13 nicklas 322   }
6382 17 Dec 13 nicklas 323   
6380 16 Dec 13 nicklas 324   internal.makeDiv = function(id, className, innerHTML)
6380 16 Dec 13 nicklas 325   {
6388 07 Jan 14 nicklas 326     var div = null;
6388 07 Jan 14 nicklas 327     if (id) div = Doc.element(id);
6388 07 Jan 14 nicklas 328     if (!div) 
6388 07 Jan 14 nicklas 329     {
6388 07 Jan 14 nicklas 330       div = document.createElement('div');
6388 07 Jan 14 nicklas 331       if (id) div.id = id;
6388 07 Jan 14 nicklas 332       if (className) div.className = className;
6388 07 Jan 14 nicklas 333       if (innerHTML) div.innerHTML = innerHTML;
6388 07 Jan 14 nicklas 334     }
6388 07 Jan 14 nicklas 335     else
6388 07 Jan 14 nicklas 336     {
6388 07 Jan 14 nicklas 337       if (className) div.className += ' ' + className;
6388 07 Jan 14 nicklas 338       div.innerHTML = innerHTML ? innerHTML : '';
6388 07 Jan 14 nicklas 339     }
6380 16 Dec 13 nicklas 340     return div;
6380 16 Dec 13 nicklas 341   }
6380 16 Dec 13 nicklas 342   
6363 29 Nov 13 nicklas 343   return joust;
6363 29 Nov 13 nicklas 344 }();
6363 29 Nov 13 nicklas 345
6380 16 Dec 13 nicklas 346
6380 16 Dec 13 nicklas 347
6363 29 Nov 13 nicklas 348 var IconStore = function()
6363 29 Nov 13 nicklas 349 {
6363 29 Nov 13 nicklas 350   var iconStore = {};
6363 29 Nov 13 nicklas 351   var iconSets = [];
6363 29 Nov 13 nicklas 352   var icons = [];
6363 29 Nov 13 nicklas 353   
6363 29 Nov 13 nicklas 354   iconStore.addDefaultIcons = function()
6363 29 Nov 13 nicklas 355   {
6363 29 Nov 13 nicklas 356     // Icons for the outline
6363 29 Nov 13 nicklas 357     iconStore.addIcon('Plus', new Icon('plus.png'));
6363 29 Nov 13 nicklas 358     iconStore.addIcon('PlusTop', new Icon('plus-top.png'));
6363 29 Nov 13 nicklas 359     iconStore.addIcon('PlusBottom', new Icon('plus-bottom.png'));
6363 29 Nov 13 nicklas 360     
6363 29 Nov 13 nicklas 361     iconStore.addIcon('Minus', new Icon('minus.png'));
6363 29 Nov 13 nicklas 362     iconStore.addIcon('MinusTop', new Icon('minus-top.png'));
6363 29 Nov 13 nicklas 363     iconStore.addIcon('MinusBottom', new Icon('minus-bottom.png'));
6363 29 Nov 13 nicklas 364
6363 29 Nov 13 nicklas 365     iconStore.addIcon('Lazy', new Icon('lazy.png'));
6363 29 Nov 13 nicklas 366     iconStore.addIcon('LazyTop', new Icon('lazy-top.png'));
6363 29 Nov 13 nicklas 367     iconStore.addIcon('LazyBottom', new Icon('lazy-bottom.png'));
6363 29 Nov 13 nicklas 368
6363 29 Nov 13 nicklas 369     iconStore.addIcon('Join', new Icon('join.png'));
6363 29 Nov 13 nicklas 370     iconStore.addIcon('JoinTop', new Icon('join-top.png'));
6363 29 Nov 13 nicklas 371     iconStore.addIcon('JoinBottom', new Icon('join-bottom.png'));
6363 29 Nov 13 nicklas 372
6363 29 Nov 13 nicklas 373     iconStore.addIcon('Line', new Icon('line.png'));
6363 29 Nov 13 nicklas 374     iconStore.addIcon('Blank', new Icon('blank.png'));
6363 29 Nov 13 nicklas 375     
6363 29 Nov 13 nicklas 376     // Icon sets for folder-like nodes
6363 29 Nov 13 nicklas 377     iconStore.addIconSet('Folder', 'folder-closed.png', 'folder-selected.png', 'folder-open.png', 'folder-selected.png');
6363 29 Nov 13 nicklas 378     iconStore.addIconSet('Root', 'root.png', 'root-selected.png');
6363 29 Nov 13 nicklas 379     iconStore.addIconSet('Home', 'home.png', 'home-selected.png');
6363 29 Nov 13 nicklas 380     iconStore.addIconSet('UserHome', 'userhome.png', 'userhome-selected.png');
6363 29 Nov 13 nicklas 381     
6363 29 Nov 13 nicklas 382     // Document nodes
6363 29 Nov 13 nicklas 383     iconStore.addIconSet('Item', 'item.png', 'item-selected.png');
6363 29 Nov 13 nicklas 384   }
6363 29 Nov 13 nicklas 385   
6363 29 Nov 13 nicklas 386   
6363 29 Nov 13 nicklas 387   iconStore.addIconSet = function(name, closed, closedSelected, open, openSelected, path)
6363 29 Nov 13 nicklas 388   {
6363 29 Nov 13 nicklas 389     var set = {};
6363 29 Nov 13 nicklas 390     set.closed = new Icon(closed, path);
6363 29 Nov 13 nicklas 391     set.closedSelected = new Icon(closedSelected || closed, path);
6363 29 Nov 13 nicklas 392     set.open = new Icon(open || closed, path);
6363 29 Nov 13 nicklas 393     set.openSelected = new Icon(openSelected || closedSelected || open || closed, path);
6363 29 Nov 13 nicklas 394     iconSets[name] = set;
6363 29 Nov 13 nicklas 395     return set;
6363 29 Nov 13 nicklas 396   }
6363 29 Nov 13 nicklas 397   
6363 29 Nov 13 nicklas 398   iconStore.getIconSet = function(name)
6363 29 Nov 13 nicklas 399   {
6363 29 Nov 13 nicklas 400     return iconSets[name];
6363 29 Nov 13 nicklas 401   }
6363 29 Nov 13 nicklas 402   
6363 29 Nov 13 nicklas 403   iconStore.getIconFromSet = function(name, open, selected)
6363 29 Nov 13 nicklas 404   {
6363 29 Nov 13 nicklas 405     var set = iconSets[name];
6380 16 Dec 13 nicklas 406     if (!set) return iconStore.nullIcon;
6363 29 Nov 13 nicklas 407     
6363 29 Nov 13 nicklas 408     var icon = null;
6363 29 Nov 13 nicklas 409     if (open && selected)
6363 29 Nov 13 nicklas 410     {
6363 29 Nov 13 nicklas 411       icon = set.openSelected;
6363 29 Nov 13 nicklas 412     }
6363 29 Nov 13 nicklas 413     else if (open)
6363 29 Nov 13 nicklas 414     {
6363 29 Nov 13 nicklas 415       icon = set.open;
6363 29 Nov 13 nicklas 416     }
6363 29 Nov 13 nicklas 417     else if (selected)
6363 29 Nov 13 nicklas 418     {
6363 29 Nov 13 nicklas 419       icon = set.closedSelected;
6363 29 Nov 13 nicklas 420     }
6363 29 Nov 13 nicklas 421     else 
6363 29 Nov 13 nicklas 422     {
6363 29 Nov 13 nicklas 423       icon = set.closed;
6363 29 Nov 13 nicklas 424     }
6380 16 Dec 13 nicklas 425     return icon || iconStore.nullIcon;
6363 29 Nov 13 nicklas 426   }
6363 29 Nov 13 nicklas 427   
6363 29 Nov 13 nicklas 428   iconStore.addIcon = function(name, icon)
6363 29 Nov 13 nicklas 429   {
6363 29 Nov 13 nicklas 430     icons[name] = icon;
6363 29 Nov 13 nicklas 431   }
6363 29 Nov 13 nicklas 432   
6363 29 Nov 13 nicklas 433   iconStore.getIcon = function(name)
6363 29 Nov 13 nicklas 434   {
6380 16 Dec 13 nicklas 435     return icons[name] || iconStore.nullIcon;
6363 29 Nov 13 nicklas 436   }
6363 29 Nov 13 nicklas 437   
6380 16 Dec 13 nicklas 438   iconStore.nullIcon = {};
6363 29 Nov 13 nicklas 439   
6380 16 Dec 13 nicklas 440   iconStore.nullIcon.toHTML = function()
6380 16 Dec 13 nicklas 441   {
6380 16 Dec 13 nicklas 442     return '';
6380 16 Dec 13 nicklas 443   }
6380 16 Dec 13 nicklas 444   
6363 29 Nov 13 nicklas 445   return iconStore;
6363 29 Nov 13 nicklas 446 }();
6363 29 Nov 13 nicklas 447
6363 29 Nov 13 nicklas 448
6363 29 Nov 13 nicklas 449 function Icon(file, path)
6363 29 Nov 13 nicklas 450 {
6363 29 Nov 13 nicklas 451   if (!path) path = App.getRoot() + 'images/joust/';
6363 29 Nov 13 nicklas 452   this.src = path+file;
6363 29 Nov 13 nicklas 453
6363 29 Nov 13 nicklas 454   // Preload the image
6363 29 Nov 13 nicklas 455   this.img = new Image();
6363 29 Nov 13 nicklas 456   this.img.src = this.src;
6363 29 Nov 13 nicklas 457 }
6363 29 Nov 13 nicklas 458
6363 29 Nov 13 nicklas 459 Icon.prototype.toHTML = function(id)
6363 29 Nov 13 nicklas 460 {
6363 29 Nov 13 nicklas 461   var html = '<img';
6363 29 Nov 13 nicklas 462   if (id) html += ' id="'+id+'"';
6363 29 Nov 13 nicklas 463   html += ' src="' + this.src + '">';
6363 29 Nov 13 nicklas 464   return html;
6363 29 Nov 13 nicklas 465 }
6363 29 Nov 13 nicklas 466
6363 29 Nov 13 nicklas 467
6363 29 Nov 13 nicklas 468