2 Scripts to create interactive Windows in SVG using ECMA script
3 Copyright (C) <2006> <Andreas Neumann>
4 Version 1.2, 2006-08-22
5 neumann@karto.baug.ethz.ch
7 http://www.carto.net/neumann/
14 Documentation: http://www.carto.net/papers/svg/gui/Window/
25 changed parameters of constructor (styling system): now an array of literals containing presentation attributes. This allows for more flexibility in Styling. Added check for number of arguments.
28 added additional parameter for .appendContent() and .insertContent(), added a .resize(method)
31 added parameter fireFunction (of type boolean) to all methods that change the window state in order to allow script controlled changes without fireing the callback function
34 renamed this.parentId to this.parentNode; this.parentNode can now also be of type node reference (g or svg element)
37 added additional event types: "moveStart", "moveEnd" and "created", added method ".addWindowDecoration()", improved documentation.
42 This ECMA script library is free software; you can redistribute it and/or
43 modify it under the terms of the GNU Lesser General Public
44 License as published by the Free Software Foundation; either
45 version 2.1 of the License, or (at your option) any later version.
47 This library is distributed in the hope that it will be useful,
48 but WITHOUT ANY WARRANTY; without even the implied warranty of
49 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
50 Lesser General Public License for more details.
52 You should have received a copy of the GNU Lesser General Public
53 License along with this library (lesser_gpl.txt); if not, write to the Free Software
54 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
58 original document site: http://www.carto.net/papers/svg/gui/Window/
59 Please contact the author in case you want to use code or ideas commercially.
60 If you use this code, please include this copyright header, the included full
61 LGPL 2.1 text and read the terms provided in the LGPL 2.1 license
62 (http://www.gnu.org/copyleft/lesser.txt)
64 -------------------------------
66 Please report bugs and send improvements to neumann@karto.baug.ethz.ch
67 If you use this control, please link to the original (http://www.carto.net/papers/svg/gui/Window/)
68 somewhere in the source-code-comment or the "about" of your project and give credits, thanks!
72 function Window(id,parentNode,width,height,transX,transY,moveable,constrXmin,constrYmin,constrXmax,constrYmax,showContent,placeholderStyles,windowStyles,margin,titleBarVisible,statusBarVisible,titleText,statusText,closeButton,minimizeButton,maximizeButton,titlebarStyles,titlebarHeight,statusbarStyles,statusbarHeight,titletextStyles,statustextStyles,buttonStyles,functionToCall) {
74 var createWindow= true;
75 if (arguments.length == nrArguments) {
77 this.parentNode = parentNode; //can be of type string (id) or node reference (svg or g node)
82 this.constrXmin = constrXmin;
83 this.constrYmin = constrYmin;
84 this.constrXmax = constrXmax;
85 this.constrYmax = constrYmax;
86 this.showContent = showContent;
87 this.placeholderStyles = placeholderStyles;
88 this.moveable = moveable;
89 this.windowStyles = windowStyles;
91 this.titleBarVisible = titleBarVisible;
92 this.statusBarVisible = statusBarVisible;
93 this.titleText = titleText;
94 this.statusText = statusText;
95 this.closeButton = closeButton;
96 this.minimizeButton = minimizeButton;
97 this.maximizeButton = maximizeButton;
98 this.titlebarStyles = titlebarStyles;
99 this.titlebarHeight = titlebarHeight;
100 this.statusbarStyles = statusbarStyles;
101 this.statusbarHeight = statusbarHeight;
102 this.titletextStyles = titletextStyles;
103 if (!this.titletextStyles["font-size"]) {
104 this.titletextStyles["font-size"] = 12;
106 this.statustextStyles = statustextStyles;
107 if (!this.statustextStyles["font-size"]) {
108 this.statustextStyles["font-size"] = 12;
110 this.buttonStyles = buttonStyles;
111 if (!this.buttonStyles["fill"]) {
112 this.buttonStyles["fill"] = "gainsboro";
114 if (!this.buttonStyles["stroke"]) {
115 this.buttonStyles["stroke"] = "dimgray";
117 if (!this.buttonStyles["stroke-width"]) {
118 this.buttonStyles["stroke-width"] = 1;
120 this.functionToCall = functionToCall;
121 //now status and reference variables
122 this.windowGroup = null; //later a reference to the window group
123 this.parentGroup = null; //later a reference to the parent group of the window
124 this.windowTitlebarGroup = null; //later a reference to the group containing the title bar elements of the group
125 this.titleBar = null; //later a reference to the titleBar rectangle
126 this.windowMainGroup = null; //later a reference to the group containing the window background and the content
127 this.windowContentGroup = null; //later a reference to the content of the window
128 this.shadowRect = null; //later a reference to a shadow rectangle
129 this.shadowTitleRect = null; //later a reference to a shadow rectangle of the titlebar
130 this.backgroundRect = null; //later a reference to the window background rectangle
131 this.closeButtonInstance = null; //later a reference to the close button
132 this.maximizeButtonInstance = null; //later a reference to the maximize button
133 this.minimizeButtonInstance = null; //later a reference to the minimize button
134 this.statusbar = null; //later a reference to the statusbar
135 this.statusTextElement = null; //later a reference to the status text element
136 this.statusTextNode = null; //later a reference to the text child node of the statusbar
137 this.titleTextNode = null; //later a reference to the text child node of the titlebar
138 this.panStatus = 0; //0 means not active, 1 means mousedown and initialized 2 means currently panning
139 this.minimized = false; //status to indicate if window is minimized
140 this.closed = false; //status to indicate if window is closed
141 this.removed = false; //status to indicate if window is removed/available
142 this.decorationGroup = null; //later a potential reference to the group containing a window decoration
143 this.decorationGroupMinimized = null; //later a potential reference to the group containing the window decoration geometry that is set to display="none" when minimized
146 createWindow = false;
147 alert("Error ("+id+"): wrong nr of arguments! You have to pass over "+nrArguments+" parameters.");
150 this.timer = new Timer(this); //a Timer instance for calling the functionToCall
151 this.timerMs = 200; //a constant of this object that is used in conjunction with the timer - functionToCall is called after 200 ms
155 alert("Could not create Window with id '"+id+"' due to errors in the constructor parameters");
159 //create a new window
160 Window.prototype.createWindow = function() {
161 var result = this.testParent();
163 //main group of the window
164 this.windowGroup = document.createElementNS(svgNS,"g");
165 this.windowGroup.setAttributeNS(null,"id",this.id);
166 this.windowGroup.setAttributeNS(null,"transform","translate("+this.transX+","+this.transY+")");
167 //create shadowRect to represent window if showContent variable is false
168 this.shadowRect = document.createElementNS(svgNS,"rect");
169 this.shadowRect.setAttributeNS(null,"width",this.width);
170 this.shadowRect.setAttributeNS(null,"height",this.height);
171 for (var attrib in this.placeholderStyles) {
172 this.shadowRect.setAttributeNS(null,attrib,this.placeholderStyles[attrib]);
174 this.shadowRect.setAttributeNS(null,"display","none");
175 this.windowGroup.appendChild(this.shadowRect);
176 //create shadowRect to represent window if showContent variable is false
177 this.shadowTitleRect = document.createElementNS(svgNS,"rect");
178 this.shadowTitleRect.setAttributeNS(null,"width",this.width);
179 this.shadowTitleRect.setAttributeNS(null,"height",this.titlebarHeight);
180 for (var attrib in this.placeholderStyles) {
181 this.shadowTitleRect.setAttributeNS(null,attrib,this.placeholderStyles[attrib]);
183 this.shadowTitleRect.setAttributeNS(null,"display","none");
184 this.windowGroup.appendChild(this.shadowTitleRect);
185 //group of the window titlebar
186 this.windowTitlebarGroup = document.createElementNS(svgNS,"g");
187 this.windowTitlebarGroup.setAttributeNS(null,"id","windowTitlebarGroup"+this.id);
188 //group containing background and content
189 this.windowMainGroup = document.createElementNS(svgNS,"g");
190 this.windowMainGroup.setAttributeNS(null,"id","windowMainGroup"+this.id);
191 //group later containing window content
192 this.windowContentGroup = document.createElementNS(svgNS,"g");
193 //create backgroundRect
194 this.backgroundRect = document.createElementNS(svgNS,"rect");
195 this.backgroundRect.setAttributeNS(null,"width",this.width);
196 this.backgroundRect.setAttributeNS(null,"height",this.height);
197 for (var attrib in this.windowStyles) {
198 this.backgroundRect.setAttributeNS(null,attrib,this.windowStyles[attrib]);
200 this.windowMainGroup.appendChild(this.backgroundRect);
201 this.windowMainGroup.appendChild(this.windowContentGroup);
202 this.windowGroup.appendChild(this.windowMainGroup);
204 if (this.titleBarVisible) {
205 this.titlebar = document.createElementNS(svgNS,"rect");
206 this.titlebar.setAttributeNS(null,"width",this.width);
207 this.titlebar.setAttributeNS(null,"height",this.titlebarHeight);
208 for (var attrib in this.titlebarStyles) {
209 this.titlebar.setAttributeNS(null,attrib,this.titlebarStyles[attrib]);
211 this.titlebar.setAttributeNS(null,"id","titleBar"+this.id);
212 this.titlebar.setAttributeNS(null,"cursor","pointer");
213 this.titlebar.addEventListener("click",this,false);
214 this.titlebar.addEventListener("mousedown",this,false);
215 this.windowTitlebarGroup.appendChild(this.titlebar);
216 var titletext = document.createElementNS(svgNS,"text");
217 titletext.setAttributeNS(null,"x",this.margin);
218 titletext.setAttributeNS(null,"y",this.titlebarHeight - (this.titlebarHeight - this.titletextStyles["font-size"]));
220 for (var attrib in this.titletextStyles) {
221 value = this.titletextStyles[attrib];
222 if (attrib == "font-size") {
225 titletext.setAttributeNS(null,attrib,value);
227 titletext.setAttributeNS(null,"pointer-events","none");
228 if (this.titleText.length > 0) {
229 this.titleTextNode = document.createTextNode(this.titleText);
232 this.titleTextNode = document.createTextNode(" ");
234 titletext.appendChild(this.titleTextNode);
235 this.windowTitlebarGroup.appendChild(titletext);
237 //test if defs section exists or create a new one
238 var defsSection = document.getElementsByTagName("defs").item(0);
240 defsSection = document.createElementNS(svgNS,"defs");
241 document.documentElement.appendChild(defsSection);
244 var buttonPosition = this.width - this.margin - this.titlebarHeight * 0.5;
245 var buttonWidth = this.titlebarHeight - this.margin * 2;
246 //create close button
247 if (this.closeButton) {
248 //test if id closeButton exists in defs section or create a new closeButton symbol
249 var closeButtonSymbol = document.getElementById("closeButton");
250 if (!closeButtonSymbol) {
251 var closeButtonSymbol = document.createElementNS(svgNS,"symbol");
252 closeButtonSymbol.setAttributeNS(null,"id","closeButton");
253 closeButtonSymbol.setAttributeNS(null,"overflow","visible");
254 //create background rect
255 var buttonRect = document.createElementNS(svgNS,"rect");
256 buttonRect.setAttributeNS(null,"x",(buttonWidth / 2 * -1));
257 buttonRect.setAttributeNS(null,"y",(buttonWidth / 2 * -1));
258 buttonRect.setAttributeNS(null,"width",buttonWidth);
259 buttonRect.setAttributeNS(null,"height",buttonWidth);
260 buttonRect.setAttributeNS(null,"fill",this.buttonStyles["fill"]);
261 buttonRect.setAttributeNS(null,"pointer-events","fill");
262 closeButtonSymbol.appendChild(buttonRect);
263 var buttonLine = document.createElementNS(svgNS,"line");
264 buttonLine.setAttributeNS(null,"x1",(buttonWidth / 2 * -1));
265 buttonLine.setAttributeNS(null,"x2",(buttonWidth / 2));
266 buttonLine.setAttributeNS(null,"y1",(buttonWidth / 2 * -1));
267 buttonLine.setAttributeNS(null,"y2",(buttonWidth / 2));
268 buttonLine.setAttributeNS(null,"stroke",this.buttonStyles["stroke"]);
269 buttonLine.setAttributeNS(null,"stroke-width",this.buttonStyles["stroke-width"]);
270 buttonLine.setAttributeNS(null,"pointer-events","none");
271 closeButtonSymbol.appendChild(buttonLine);
272 var buttonLine = document.createElementNS(svgNS,"line");
273 buttonLine.setAttributeNS(null,"x1",(buttonWidth / 2));
274 buttonLine.setAttributeNS(null,"x2",(buttonWidth / 2 * -1));
275 buttonLine.setAttributeNS(null,"y1",(buttonWidth / 2 * -1));
276 buttonLine.setAttributeNS(null,"y2",(buttonWidth / 2));
277 buttonLine.setAttributeNS(null,"stroke",this.buttonStyles["stroke"]);
278 buttonLine.setAttributeNS(null,"stroke-width",this.buttonStyles["stroke-width"]);
279 buttonLine.setAttributeNS(null,"pointer-events","none");
280 closeButtonSymbol.appendChild(buttonLine);
281 defsSection.appendChild(closeButtonSymbol);
283 this.closeButtonInstance = document.createElementNS(svgNS,"use");
284 this.closeButtonInstance.setAttributeNS(null,"x",buttonPosition);
285 this.closeButtonInstance.setAttributeNS(null,"y",this.titlebarHeight * 0.5);
286 this.closeButtonInstance.setAttributeNS(null,"cursor","pointer");
287 this.closeButtonInstance.setAttributeNS(null,"id","closeButton"+this.id);
288 this.closeButtonInstance.setAttributeNS(xlinkNS,"href","#closeButton");
289 this.closeButtonInstance.addEventListener("click",this,false);
290 this.windowTitlebarGroup.appendChild(this.closeButtonInstance);
291 buttonPosition -= this.titlebarHeight;
294 //create maximize button
295 if (this.maximizeButton) {
296 //test if id maximizeButton exists in defs section or create a new maximizeButton symbol
297 var maximizeButtonSymbol = document.getElementById("maximizeButton");
298 if (!maximizeButtonSymbol) {
299 var maximizeButtonSymbol = document.createElementNS(svgNS,"symbol");
300 maximizeButtonSymbol.setAttributeNS(null,"id","maximizeButton");
301 maximizeButtonSymbol.setAttributeNS(null,"overflow","visible");
302 //create background rect
303 var buttonRect = document.createElementNS(svgNS,"rect");
304 buttonRect.setAttributeNS(null,"x",(buttonWidth / 2 * -1));
305 buttonRect.setAttributeNS(null,"y",(buttonWidth / 2 * -1));
306 buttonRect.setAttributeNS(null,"width",buttonWidth);
307 buttonRect.setAttributeNS(null,"height",buttonWidth);
308 for (var attrib in this.buttonStyles) {
309 buttonRect.setAttributeNS(null,attrib,this.buttonStyles[attrib]);
311 buttonRect.setAttributeNS(null,"pointer-events","fill");
312 maximizeButtonSymbol.appendChild(buttonRect);
313 defsSection.appendChild(maximizeButtonSymbol);
315 this.maximizeButtonInstance = document.createElementNS(svgNS,"use");
316 this.maximizeButtonInstance.setAttributeNS(null,"x",buttonPosition);
317 this.maximizeButtonInstance.setAttributeNS(null,"y",this.titlebarHeight * 0.5);
318 this.maximizeButtonInstance.setAttributeNS(null,"cursor","pointer");
319 this.maximizeButtonInstance.setAttributeNS(null,"id","maximizeButton"+this.id);
320 this.maximizeButtonInstance.setAttributeNS(xlinkNS,"href","#maximizeButton");
321 this.maximizeButtonInstance.addEventListener("click",this,false);
322 this.windowTitlebarGroup.appendChild(this.maximizeButtonInstance);
323 buttonPosition -= this.titlebarHeight;
326 //create minimize button
327 if (this.minimizeButton) {
328 //test if id minimizeButton exists in defs section or create a new minimizeButton symbol
329 var minimizeButtonSymbol = document.getElementById("minimizeButton");
330 if (!minimizeButtonSymbol) {
331 var minimizeButtonSymbol = document.createElementNS(svgNS,"symbol");
332 minimizeButtonSymbol.setAttributeNS(null,"id","minimizeButton");
333 minimizeButtonSymbol.setAttributeNS(null,"overflow","visible");
334 //create background rect
335 var buttonRect = document.createElementNS(svgNS,"rect");
336 buttonRect.setAttributeNS(null,"x",(buttonWidth / 2 * -1));
337 buttonRect.setAttributeNS(null,"y",(buttonWidth / 2 * -1));
338 buttonRect.setAttributeNS(null,"width",buttonWidth);
339 buttonRect.setAttributeNS(null,"height",buttonWidth);
340 buttonRect.setAttributeNS(null,"fill",this.buttonStyles["fill"]);
341 buttonRect.setAttributeNS(null,"pointer-events","fill");
342 minimizeButtonSymbol.appendChild(buttonRect);
344 var buttonLine = document.createElementNS(svgNS,"line");
345 buttonLine.setAttributeNS(null,"x1",(buttonWidth / 2));
346 buttonLine.setAttributeNS(null,"x2",(buttonWidth / 2 * -1));
347 buttonLine.setAttributeNS(null,"y1",(buttonWidth / 2));
348 buttonLine.setAttributeNS(null,"y2",(buttonWidth / 2));
349 buttonLine.setAttributeNS(null,"stroke",this.buttonStyles["stroke"]);
350 buttonLine.setAttributeNS(null,"stroke-width",this.buttonStyles["stroke-width"]);
351 minimizeButtonSymbol.appendChild(buttonLine);
352 defsSection.appendChild(minimizeButtonSymbol);
354 this.minimizeButtonInstance = document.createElementNS(svgNS,"use");
355 this.minimizeButtonInstance.setAttributeNS(null,"x",buttonPosition);
356 this.minimizeButtonInstance.setAttributeNS(null,"y",this.titlebarHeight * 0.5);
357 this.minimizeButtonInstance.setAttributeNS(null,"cursor","pointer");
358 this.minimizeButtonInstance.setAttributeNS(null,"id","minimizeButton"+this.id);
359 this.minimizeButtonInstance.setAttributeNS(xlinkNS,"href","#minimizeButton");
360 this.minimizeButtonInstance.addEventListener("click",this,false);
361 this.windowTitlebarGroup.appendChild(this.minimizeButtonInstance);
362 buttonPosition -= this.titlebarHeight;
365 if (this.statusBarVisible) {
366 this.statusbar = document.createElementNS(svgNS,"rect");
367 this.statusbar.setAttributeNS(null,"y",(this.height - this.statusbarHeight));
368 this.statusbar.setAttributeNS(null,"width",this.width);
369 this.statusbar.setAttributeNS(null,"height",this.statusbarHeight);
370 for (var attrib in this.statusbarStyles) {
371 this.statusbar.setAttributeNS(null,attrib,this.statusbarStyles[attrib]);
373 this.windowMainGroup.appendChild(this.statusbar);
374 this.statusTextElement = document.createElementNS(svgNS,"text");
375 this.statusTextElement.setAttributeNS(null,"x",this.margin);
376 this.statusTextElement.setAttributeNS(null,"y",this.height - (this.statusbarHeight - this.statustextStyles["font-size"]));
378 for (var attrib in this.statustextStyles) {
379 value = this.statustextStyles[attrib];
380 if (attrib == "font-size") {
383 this.statusTextElement.setAttributeNS(null,attrib,value);
385 this.statusTextElement.setAttributeNS(null,"pointer-events","none");
386 if (this.statusText.length > 0) {
387 this.statusTextNode = document.createTextNode(this.statusText);
390 this.statusTextNode = document.createTextNode(" ");
392 this.statusTextElement.appendChild(this.statusTextNode);
393 this.windowMainGroup.appendChild(this.statusTextElement);
396 //append titlebar group to window group
397 this.windowGroup.appendChild(this.windowTitlebarGroup);
399 //finally append group to windows group
400 this.parentGroup.appendChild(this.windowGroup);
402 //issue event that window was created
403 this.timer.setTimeout("fireFunction",this.timerMs,"created");
406 alert("could not create or reference 'parentNode' of window with id '"+this.id+"'");
410 //test if window group exists or create a new group at the end of the file
411 Window.prototype.testParent = function() {
412 //test if of type object
413 var nodeValid = false;
414 if (typeof(this.parentNode) == "object") {
415 if (this.parentNode.nodeName == "svg" || this.parentNode.nodeName == "g") {
416 this.parentGroup = this.parentNode;
420 else if (typeof(this.parentNode) == "string") {
421 //first test if Windows group exists
422 if (!document.getElementById(this.parentNode)) {
423 this.parentGroup = document.createElementNS(svgNS,"g");
424 this.parentGroup.setAttributeNS(null,"id",this.parentNode);
425 document.documentElement.appendChild(this.parentGroup);
429 this.parentGroup = document.getElementById(this.parentNode);
436 //central mouse-event handling
437 Window.prototype.handleEvent = function(evt) {
438 if (evt.type == "click") {
439 var elId = evt.currentTarget.getAttributeNS(null,"id");
440 if (elId == "closeButton"+this.id) {
443 if (elId == "maximizeButton"+this.id) {
446 if (elId == "minimizeButton"+this.id) {
449 if (elId == "titleBar"+this.id || elId == "decoGroup"+this.id) {
450 if (evt.detail == 2) {
451 if (this.minimized) {
460 if (evt.type == "mousedown") {
461 var elId = evt.currentTarget.getAttributeNS(null,"id");
462 if (elId == "titleBar"+this.id || elId == "decoGroup"+this.id) {
463 //put it to the front
464 this.parentGroup.appendChild(this.windowGroup);
467 //var coords = myMapApp.calcCoord(evt,document.documentElement);
468 var coords = myMapApp.calcCoord(evt,this.parentGroup);
469 this.panCoords = coords;
470 document.documentElement.addEventListener("mousemove",this,false);
471 document.documentElement.addEventListener("mouseup",this,false);
472 if (!this.showContent) {
473 this.windowTitlebarGroup.setAttributeNS(null,"display","none");
474 this.windowMainGroup.setAttributeNS(null,"display","none");
475 if (this.minimized) {
476 this.shadowTitleRect.setAttributeNS(null,"display","inherit");
479 this.shadowRect.setAttributeNS(null,"display","inherit");
483 if (this.titleBarVisible) {
484 this.titlebar.setAttributeNS(null,"cursor","move");
486 if (this.decorationGroup) {
487 this.decorationGroup.setAttributeNS(null,"cursor","move");
490 this.windowGroup.setAttributeNS(batikNS,"static","true");
491 this.fireFunction("moveStart");
495 if (evt.type == "mousemove") {
496 if (this.panStatus == 1) {
497 //var coords = myMapApp.calcCoord(evt,document.documentElement);
498 var coords = myMapApp.calcCoord(evt,this.parentGroup);
499 if (coords.x < this.constrXmin || coords.x > this.constrXmax || coords.y < this.constrYmin || coords.y > this.constrYmax) {
503 this.transX += coords.x - this.panCoords.x;
504 this.transY += coords.y - this.panCoords.y;
506 if (this.transX < this.constrXmin) {
507 this.transX = this.constrXmin;
509 if (this.transY < this.constrYmin) {
510 this.transY = this.constrYmin;
512 if ((this.transX + this.width) > (this.constrXmax)) {
513 this.transX = this.constrXmax - this.width;
515 if (this.minimized) {
516 if ((this.transY + this.titlebarHeight) > (this.constrYmax)) {
517 this.transY = this.constrYmax - this.titlebarHeight;
521 if ((this.transY + this.height) > (this.constrYmax)) {
522 this.transY = this.constrYmax - this.height;
525 this.windowGroup.setAttributeNS(null,"transform","translate("+this.transX+","+this.transY+")");
526 this.panCoords = coords;
527 this.timer.setTimeout("fireFunction",this.timerMs,"moved");
531 if (evt.type == "mouseup") {
532 if (this.panStatus == 1) {
538 Window.prototype.fireFunction = function(evtType) {
539 if (typeof(this.functionToCall) == "function") {
540 this.functionToCall(this.id,evtType);
542 if (typeof(this.functionToCall) == "object") {
543 this.functionToCall.windowStatusChanged(this.id,evtType);
545 if (typeof(this.functionToCall) == undefined) {
550 //helper method to stop the dragging mode
551 Window.prototype.stopDrag = function() {
552 this.windowGroup.removeAttributeNS(batikNS,"static");
553 document.documentElement.removeEventListener("mousemove",this,false);
554 document.documentElement.removeEventListener("mouseup",this,false);
555 if (!this.showContent) {
556 this.windowTitlebarGroup.setAttributeNS(null,"display","inherit");
557 if (this.minimized) {
558 this.shadowTitleRect.setAttributeNS(null,"display","none");
561 this.shadowRect.setAttributeNS(null,"display","none");
562 this.windowMainGroup.setAttributeNS(null,"display","inherit");
566 if (this.titleBarVisible) {
567 this.titlebar.setAttributeNS(null,"cursor","pointer");
569 if (this.decorationGroup) {
570 this.decorationGroup.setAttributeNS(null,"cursor","pointer");
573 this.timer.setTimeout("fireFunction",this.timerMs,"moveEnd");
578 Window.prototype.minimize = function(fireFunction) {
579 this.windowMainGroup.setAttributeNS(null,"display","none");
580 if (this.decorationGroupMinimized) {
581 this.decorationGroupMinimized.setAttributeNS(null,"display","none");
583 this.minimized = true;
585 this.timer.setTimeout("fireFunction",this.timerMs,"minimized");
590 Window.prototype.maximize = function(fireFunction) {
591 this.windowMainGroup.setAttributeNS(null,"display","inherit");
592 if (this.decorationGroupMinimized) {
593 this.decorationGroupMinimized.setAttributeNS(null,"display","inherit");
595 if ((this.transY + this.height) > (this.constrYmax)) {
596 this.transY = this.constrYmax - this.height;
597 this.windowGroup.setAttributeNS(null,"transform","translate("+this.transX+","+this.transY+")");
599 this.minimized = false;
601 this.timer.setTimeout("fireFunction",this.timerMs,"maximized");
605 //open a closed window
606 Window.prototype.close = function(fireFunction) {
607 this.windowGroup.setAttributeNS(null,"display","none");
610 this.timer.setTimeout("fireFunction",this.timerMs,"closed");
614 //close window, after closing the window is still in its previous state and can be re-opened
615 Window.prototype.open = function(fireFunction) {
617 this.windowGroup.setAttributeNS(null,"display","inherit");
620 this.timer.setTimeout("fireFunction",this.timerMs,"opened");
624 alert("window " + this.id + " is already removed");
628 //resize window and reposition it into constrained coords
629 Window.prototype.resize = function(width,height,fireFunction) {
631 this.height = height;
633 this.shadowRect.setAttributeNS(null,"width",this.width);
634 this.shadowRect.setAttributeNS(null,"height",this.height);
635 this.shadowTitleRect.setAttributeNS(null,"width",this.width);
636 //adopt background rect
637 this.backgroundRect.setAttributeNS(null,"width",this.width);
638 this.backgroundRect.setAttributeNS(null,"height",this.height);
640 if (this.titleBarVisible) {
641 this.titlebar.setAttributeNS(null,"width",this.width);
643 var buttonPosition = this.width - this.margin - this.titlebarHeight * 0.5;
644 if (this.closeButton) {
645 this.closeButtonInstance.setAttributeNS(null,"x",buttonPosition);
646 buttonPosition -= this.titlebarHeight;
648 if (this.maximizeButton) {
649 this.maximizeButtonInstance.setAttributeNS(null,"x",buttonPosition);
650 buttonPosition -= this.titlebarHeight;
652 if (this.minimizeButton) {
653 this.minimizeButtonInstance.setAttributeNS(null,"x",buttonPosition);
655 if (this.statusBarVisible) {
656 this.statusbar.setAttributeNS(null,"y",(this.height - this.statusbarHeight));
657 this.statusbar.setAttributeNS(null,"width",this.width);
658 this.statusTextElement.setAttributeNS(null,"y",this.height - (this.statusbarHeight - this.statustextStyles["font-size"]));
661 if (this.transX < this.constrXmin) {
662 this.transX = this.constrXmin;
664 if (this.transY < this.constrYmin) {
665 this.transY = this.constrYmin;
667 if ((this.transX + this.width) > (this.constrXmax)) {
668 this.transX = this.constrXmax - this.width;
670 if (this.minimized) {
671 if ((this.transY + this.titlebarHeight) > (this.constrYmax)) {
672 this.transY = this.constrYmax - this.titlebarHeight;
676 if ((this.transY + this.height) > (this.constrYmax)) {
677 this.transY = this.constrYmax - this.height;
680 this.windowGroup.setAttributeNS(null,"transform","translate("+this.transX+","+this.transY+")");
682 this.fireFunction("resized");
687 Window.prototype.remove = function(fireFunction) {
689 this.windowGroup.parentGroup.removeChild(this.windowGroup);
692 this.timer.setTimeout("fireFunction",this.timerMs,"removed");
697 //change content of statusBar
698 Window.prototype.setStatusText = function(statusText) {
699 if (this.statusBarVisible) {
700 this.statusText = statusText;
701 if (this.statusText.length > 0) {
702 this.statusTextNode.nodeValue = this.statusText;
705 this.statusTextNode.nodeValue = " ";
710 alert("there is no statusbar available");
714 //change content of statusBar
715 Window.prototype.setTitleText = function(titleText) {
716 this.titleText = titleText;
717 if (titleText.length > 0) {
718 this.titleTextNode.nodeValue = titleText;
721 this.titleTextNode.nodeValue = " ";
725 //move a window to a certain position (upper left corner)
726 Window.prototype.moveTo = function(coordx,coordy,fireFunction) {
727 this.transX = coordx;
728 this.transY = coordy;
730 if (this.transX < this.constrXmin) {
731 this.transX = this.constrXmin;
733 if (this.transY < this.constrYmin) {
734 this.transY = this.constrYmin;
736 if ((this.transX + this.width) > (this.constrXmax)) {
737 this.transX = this.constrXmax - this.width;
739 if (this.minimized) {
740 if ((this.transY + this.titlebarHeight) > (this.constrYmax)) {
741 this.transY = this.constrYmax - this.titlebarHeight;
745 if ((this.transY + this.height) > (this.constrYmax)) {
746 this.transY = this.constrYmax - this.height;
749 this.windowGroup.setAttributeNS(null,"transform","translate("+this.transX+","+this.transY+")");
751 this.timer.setTimeout("fireFunction",this.timerMs,"movedTo");
755 //append new content to the window main group
756 Window.prototype.appendContent = function(node,inheritDisplay) {
757 if (typeof(node) == "string") {
758 node = document.getElementById(node);
760 if (inheritDisplay) {
761 node.setAttributeNS(null,"display","inherit");
763 this.windowContentGroup.appendChild(node);
766 //remove new content from the window main group
767 Window.prototype.removeContent = function(node) {
768 if (typeof(node) == "string") {
769 node = document.getElementById(node);
771 this.windowContentGroup.removeChild(node);
774 //remove new content from the window main group
775 Window.prototype.insertContentBefore = function(node,referenceNode,inheritDisplay) {
776 if (typeof(node) == "string") {
777 node = document.getElementById(node);
779 if (typeof(referenceNode) == "string") {
780 referenceNode = document.getElementById(referenceNode);
782 if (inheritDisplay) {
783 node.setAttributeNS(null,"display","inherit");
785 this.windowContentGroup.insertBefore(node,referenceNode);
788 //hide content of Window
789 Window.prototype.hideContents = function() {
790 this.windowContentGroup.setAttributeNS(null,"display","none");
793 //show content of Window
794 Window.prototype.showContents = function() {
795 this.windowContentGroup.setAttributeNS(null,"display","inherit");
798 //add window decoration
799 Window.prototype.addWindowDecoration = function(node,mayTriggerMoving,topOrBottom) {
800 if (typeof(node) == "string") {
801 node = document.getElementById(node);
803 if (this.decorationGroup) {
804 var parent = this.decorationGroup.parentNode;
805 parent.removeChild(this.decorationGroup);
807 if (topOrBottom == "bottom") {
808 this.decorationGroup = this.windowGroup.insertBefore(node,this.windowGroup.firstChild);
810 else if (topOrBottom == "top") {
811 this.decorationGroup = this.windowTitlebarGroup.insertBefore(node,this.windowTitlebarGroup.firstChild);
814 alert("Error in window with id '"+this.id+"': you have to specify 'top' or 'bottom' for the variable 'topOrBottom'.");
816 if (mayTriggerMoving) {
817 this.decorationGroup.setAttributeNS(null,"id","decoGroup"+this.id);
818 this.decorationGroup.setAttributeNS(null,"cursor","pointer");
819 this.decorationGroup.addEventListener("click",this,false);
820 this.decorationGroup.addEventListener("mousedown",this,false);
822 //see if there is a sub group/element that should be hidden when minimized
824 this.decorationGroupMinimized = document.getElementById("decoGroupMinimized"+this.id);
825 if (this.minimized) {
826 this.decorationGroupMinimized.setAttributeNS(null,"display","none");
830 this.decorationGroupMinimized = null;