1 /** 2 * Creates a new FloatPanelFactory. This factory object can create new instances 3 * of mindmaps.FloatPanel that are constrained inside the container. 4 * 5 * @constructor 6 * @param container 7 */ 8 mindmaps.FloatPanelFactory = function(container) { 9 var $container = container.getContent(); 10 var dialogs = []; 11 var paddingRight = 15; 12 var paddingTop = 5; 13 14 function setPosition(dialog) { 15 // reposition dialog on window resize 16 container.subscribe(mindmaps.CanvasContainer.Event.RESIZED, function() { 17 dialogs.forEach(function(dialog) { 18 if (dialog.visible) { 19 dialog.ensurePosition(); 20 } 21 }); 22 }); 23 24 var ccw = $container.outerWidth(); 25 var hh = $container.offset().top; 26 var dw = dialog.width(); 27 var dh = dialog.height(); 28 var heightOffset = dialogs.reduce(function(memo, dialog) { 29 return memo + dialog.height() + paddingTop; 30 }, 0); 31 32 dialog.setPosition(ccw - dw - paddingRight, hh + paddingTop 33 + heightOffset); 34 } 35 36 /** 37 * Creates a new FloatPanel. 38 * 39 * @param {String} caption the float panel title 40 * @param {jQuery} $content the content as a jquery object 41 * @returns {mindmaps.FloatPanel} 42 */ 43 this.create = function(caption, $content) { 44 var dialog = new mindmaps.FloatPanel(caption, $container, $content); 45 setPosition(dialog); 46 dialogs.push(dialog); 47 return dialog; 48 }; 49 }; 50 51 /** 52 * A reusable, draggable panel gui element. The panel is contained within the 53 * container. When a $hideTarget is set, the hide/show animations will show a 54 * transfer effect. 55 * 56 * @constructor 57 * @param {String} caption the float panel title 58 * @param {jQuery} $container the surrounding container jquery object 59 * @param {jQuery} $content the content as a jquery object 60 */ 61 mindmaps.FloatPanel = function(caption, $container, $content) { 62 var self = this; 63 var animating = false; 64 65 this.caption = caption; 66 this.visible = false; 67 this.animationDuration = 400; 68 69 /** 70 * Replaces the content in the panel. 71 * 72 * @param {jQuery} $content 73 */ 74 this.setContent = function($content) { 75 this.clearContent(); 76 $("div.ui-dialog-content", this.$widget).append($content); 77 }; 78 79 /** 80 * Clears the content of the panel. 81 */ 82 this.clearContent = function() { 83 $("div.ui-dialog-content", this.$widget).children().detach(); 84 }; 85 86 /** 87 * @private 88 */ 89 this.$widget = (function() { 90 var $panel = $("#template-float-panel").tmpl({ 91 title : caption 92 }); 93 94 // hide button 95 $panel.find(".ui-dialog-titlebar-close").click(function() { 96 self.hide(); 97 }); 98 99 // add content panel 100 if ($content) { 101 $panel.find(".ui-dialog-content").append($content); 102 } 103 104 // make draggable, hide, append to container 105 $panel.draggable({ 106 containment : "parent", 107 handle : "div.ui-dialog-titlebar", 108 opacity : 0.75 109 }).hide().appendTo($container); 110 111 return $panel; 112 })(); 113 114 /** 115 * Hides the panel. Will show transfer effect if $hideTarget is set. 116 */ 117 this.hide = function() { 118 if (!animating && this.visible) { 119 this.visible = false; 120 this.$widget.fadeOut(this.animationDuration * 1.5); 121 122 // show transfer effect is hide target is set 123 if (this.$hideTarget) { 124 this.transfer(this.$widget, this.$hideTarget); 125 } 126 } 127 }; 128 129 /** 130 * Shows the panel. Will show transfer effect if $hideTarget is set. 131 */ 132 this.show = function() { 133 if (!animating && !this.visible) { 134 this.visible = true; 135 this.$widget.fadeIn(this.animationDuration * 1.5); 136 this.ensurePosition(); 137 138 // show transfer effect is hide target is set 139 if (this.$hideTarget) { 140 this.transfer(this.$hideTarget, this.$widget); 141 } 142 } 143 }; 144 145 /** 146 * Shows or hides the panel. 147 */ 148 this.toggle = function() { 149 if (this.visible) { 150 this.hide(); 151 } else { 152 this.show(); 153 } 154 }; 155 156 /** 157 * Shows a transfer effect. 158 * 159 * @private 160 * @param {jQuery} $from 161 * @param {jQuery} $to 162 */ 163 this.transfer = function($from, $to) { 164 animating = true; 165 var endPosition = $to.offset(), animation = { 166 top : endPosition.top, 167 left : endPosition.left, 168 height : $to.innerHeight(), 169 width : $to.innerWidth() 170 }, startPosition = $from.offset(), transfer = $( 171 '<div class="ui-effects-transfer"></div>').appendTo( 172 document.body).css({ 173 top : startPosition.top, 174 left : startPosition.left, 175 height : $from.innerHeight(), 176 width : $from.innerWidth(), 177 position : 'absolute' 178 }).animate(animation, this.animationDuration, "linear", function() { 179 // end 180 transfer.remove(); 181 animating = false; 182 }); 183 }; 184 185 /** 186 * 187 * @returns {Number} the width. 188 */ 189 this.width = function() { 190 return this.$widget.outerWidth(); 191 }; 192 193 /** 194 * 195 * @returns {Number} the height. 196 */ 197 this.height = function() { 198 return this.$widget.outerHeight(); 199 }; 200 201 /** 202 * 203 * @returns {Object} the offset 204 */ 205 this.offset = function() { 206 return this.$widget.offset(); 207 }; 208 209 /** 210 * Sets the position of the panel relative to the container. 211 * 212 * @param {Number} x 213 * @param {Number} y 214 */ 215 this.setPosition = function(x, y) { 216 this.$widget.offset({ 217 left : x, 218 top : y 219 }); 220 }; 221 222 /** 223 * Moves panel into view port if position exceeds the bounds of the 224 * container. 225 * 226 * @private 227 */ 228 this.ensurePosition = function() { 229 var cw = $container.outerWidth(); 230 var ch = $container.outerHeight(); 231 var col = $container.offset().left; 232 var cot = $container.offset().top; 233 var dw = this.width(); 234 var dh = this.height(); 235 var dol = this.offset().left; 236 var dot = this.offset().top; 237 238 // window width is too small for current dialog position but bigger than 239 // dialog width 240 if (cw + col < dw + dol && cw >= dw) { 241 this.setPosition(cw + col - dw, dot); 242 } 243 244 // window height is too small for current dialog position but bigger 245 // than dialog height 246 if (ch + cot < dh + dot && ch >= dh) { 247 this.setPosition(dol, ch + cot - dh); 248 } 249 }; 250 251 /** 252 * Sets the hide target for the panel. 253 * 254 * @param {jQuery} $target 255 */ 256 this.setHideTarget = function($target) { 257 this.$hideTarget = $target; 258 }; 259 };