1 /* ************************************************************************
3 qooxdoo - the new era of web development
8 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
11 LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
14 * Sebastian Werner (wpbasti)
15 * Andreas Ecker (ecker)
17 ************************************************************************ */
19 /* ************************************************************************
23 ************************************************************************ */
25 qx.OO.defineClass("qx.renderer.layout.DockLayoutImpl", qx.renderer.layout.LayoutImpl,
27 qx.renderer.layout.LayoutImpl.call(this, vWidget);
33 [01] COMPUTE BOX DIMENSIONS FOR AN INDIVIDUAL CHILD
34 [02] COMPUTE NEEDED DIMENSIONS FOR AN INDIVIDUAL CHILD
35 [03] COMPUTE NEEDED DIMENSIONS FOR ALL CHILDREN
36 [04] UPDATE LAYOUT WHEN A CHILD CHANGES ITS OUTER DIMENSIONS
37 [05] UPDATE CHILD ON INNER DIMENSION CHANGES OF LAYOUT
38 [06] UPDATE LAYOUT ON JOB QUEUE FLUSH
39 [07] UPDATE CHILDREN ON JOB QUEUE FLUSH
40 [08] CHILDREN ADD/REMOVE/MOVE HANDLING
41 [09] FLUSH LAYOUT QUEUES OF CHILDREN
46 Inherits from qx.renderer.layout.LayoutImpl:
47 [02] COMPUTE NEEDED DIMENSIONS FOR AN INDIVIDUAL CHILD
48 [03] COMPUTE NEEDED DIMENSIONS FOR ALL CHILDREN
49 [04] UPDATE LAYOUT WHEN A CHILD CHANGES ITS OUTER DIMENSIONS
50 [08] CHILDREN ADD/REMOVE/MOVE HANDLING
58 ---------------------------------------------------------------------------
59 [00] ADDITIONAL GLOBAL DATA AND METHODS
60 ---------------------------------------------------------------------------
63 qx.renderer.layout.DockLayoutImpl.METHOD_LOCATION = "layoutChild_location_";
65 qx.renderer.layout.DockLayoutImpl._childRanking = {
66 vertical : function(c) { return c.getVerticalAlign() ? 1e6 : c.getHorizontalAlign() ? 2e6 : 3e6; },
67 horizontal : function(c) { return c.getHorizontalAlign() ? 1e6 : c.getVerticalAlign() ? 2e6 : 3e6; },
68 ordered : function(c) { return c.getHorizontalAlign() || c.getVerticalAlign() ? 1e6 : 2e6; }
71 qx.renderer.layout.DockLayoutImpl._childCheck =
73 common : function(vChild) {
74 if (!(vChild._computedLeftTypeNull && vChild._computedRightTypeNull && vChild._computedTopTypeNull && vChild._computedBottomTypeNull)) {
75 throw new Error("qx.renderer.layout.DockLayoutImpl: It is not allowed to define any location values for children: " + vChild + "!");
79 horizontal : function(vChild)
81 if (!(vChild._computedMinHeightTypeNull && vChild._computedHeightTypeNull && vChild._computedMaxHeightTypeNull)) {
82 throw new Error("qx.renderer.layout.DockLayoutImpl: It is not allowed to define any vertical dimension for 'horizontal' placed children: " + vChild + "!");
86 vertical : function(vChild)
88 if (!(vChild._computedMinWidthTypeNull && vChild._computedWidthTypeNull && vChild._computedMaxWidthTypeNull)) {
89 throw new Error("qx.renderer.layout.DockLayoutImpl: It is not allowed to define any horizontal dimension for 'vertical' placed children: " + vChild + "!");
93 "default" : function(vChild)
95 qx.renderer.layout.DockLayoutImpl._childCheck.horizontal(vChild);
96 qx.renderer.layout.DockLayoutImpl._childCheck.vertical(vChild);
107 ---------------------------------------------------------------------------
108 [01] COMPUTE BOX DIMENSIONS FOR AN INDIVIDUAL CHILD
109 ---------------------------------------------------------------------------
113 Compute and return the box width of the given child
115 qx.Proto.computeChildBoxWidth = function(vChild)
117 if (this.getChildAlignMode(vChild) == "horizontal") {
118 return vChild.getWidthValue() || vChild._computeBoxWidthFallback();
121 return this.getWidget().getInnerWidth() - this._lastLeft - this._lastRight;
125 Compute and return the box height of the given child
127 qx.Proto.computeChildBoxHeight = function(vChild)
129 if (this.getChildAlignMode(vChild) == "vertical") {
130 return vChild.getHeightValue() || vChild._computeBoxHeightFallback();
133 return this.getWidget().getInnerHeight() - this._lastTop - this._lastBottom;
143 ---------------------------------------------------------------------------
144 [05] UPDATE CHILD ON INNER DIMENSION CHANGES OF LAYOUT
145 ---------------------------------------------------------------------------
149 Actions that should be done if the inner width of the widget was changed.
150 Normally this includes update to percent values and ranges.
152 qx.Proto.updateChildOnInnerWidthChange = function(vChild)
154 vChild._recomputePercentX();
155 vChild.addToLayoutChanges("location");
157 // inform the caller if there were any notable changes occured
162 Actions that should be done if the inner height of the widget was changed.
163 Normally this includes update to percent values and ranges.
165 qx.Proto.updateChildOnInnerHeightChange = function(vChild)
167 vChild._recomputePercentY();
168 vChild.addToLayoutChanges("location");
170 // inform the caller if there were any notable changes occured
179 ---------------------------------------------------------------------------
180 [06] UPDATE LAYOUT ON JOB QUEUE FLUSH
181 ---------------------------------------------------------------------------
185 Invalidate and recompute things because of job in queue (before the rest of job handling will be executed).
187 qx.Proto.updateSelfOnJobQueueFlush = qx.util.Return.returnFalse;
196 ---------------------------------------------------------------------------
197 [07] UPDATE CHILDREN ON JOB QUEUE FLUSH
198 ---------------------------------------------------------------------------
202 Updates children on special jobs
204 qx.Proto.updateChildrenOnJobQueueFlush = function(vQueue)
206 if (vQueue.mode || vQueue.addChild || vQueue.removeChild) {
207 this.getWidget()._addChildrenToLayoutQueue("location");
220 ---------------------------------------------------------------------------
221 [09] FLUSH LAYOUT QUEUES OF CHILDREN
222 ---------------------------------------------------------------------------
226 This method have full control of the order in which the
227 registered (or also non-registered) children should be
228 layouted on the horizontal axis.
230 qx.Proto.flushChildrenQueue = function(vChildrenQueue)
232 var vWidget=this.getWidget(), vChildren=vWidget.getVisibleChildren(), vChildrenLength=vChildren.length, vMode=vWidget.getMode();
235 this._lastLeft = this._lastRight = this._lastTop = this._lastBottom = 0;
238 var vRankImpl = qx.renderer.layout.DockLayoutImpl._childRanking[vMode];
239 var vOrderedChildren = qx.lang.Array.copy(vChildren).sort(function(c1, c2) {
240 return (vRankImpl(c1) + vChildren.indexOf(c1)) - (vRankImpl(c2) + vChildren.indexOf(c2));
244 for (var i=0; i<vChildrenLength; i++) {
245 vWidget._layoutChild(vOrderedChildren[i]);
249 qx.Proto.getChildAlign = function(vChild) {
250 return vChild.getVerticalAlign() || vChild.getHorizontalAlign() || "default";
253 qx.Proto.getChildAlignMode = function(vChild) {
254 return vChild.getVerticalAlign() ? "vertical" : vChild.getHorizontalAlign() ? "horizontal" : "default";
264 ---------------------------------------------------------------------------
266 ---------------------------------------------------------------------------
270 This is called from qx.ui.core.Widget and it's task is to apply the layout
271 (excluding border and padding) to the child.
273 qx.Proto.layoutChild = function(vChild, vJobs)
275 qx.renderer.layout.DockLayoutImpl._childCheck.common(vChild);
276 qx.renderer.layout.DockLayoutImpl._childCheck[this.getChildAlignMode(vChild)](vChild);
278 this.layoutChild_sizeX_essentialWrapper(vChild, vJobs);
279 this.layoutChild_sizeY_essentialWrapper(vChild, vJobs);
281 this.layoutChild_sizeLimitX(vChild, vJobs);
282 this.layoutChild_sizeLimitY(vChild, vJobs);
284 this[qx.renderer.layout.DockLayoutImpl.METHOD_LOCATION + this.getChildAlign(vChild)](vChild, vJobs);
287 qx.Proto.layoutChild_location_top = function(vChild, vJobs)
289 vChild._applyRuntimeTop(this._lastTop);
290 vChild._applyRuntimeLeft(this._lastLeft);
292 this.layoutChild_location_horizontal(vChild);
294 this._lastTop += vChild.getBoxHeight();
297 qx.Proto.layoutChild_location_left = function(vChild, vJobs)
299 vChild._applyRuntimeLeft(this._lastLeft);
300 vChild._applyRuntimeTop(this._lastTop);
302 this.layoutChild_location_vertical(vChild);
304 this._lastLeft += vChild.getBoxWidth();
313 if (qx.sys.Client.getInstance().isMshtml() || qx.sys.Client.getInstance().isOpera())
315 qx.Proto._applyComputedWidth = function(vChild)
317 // direct recompute (need to be done, while layouting as the
318 // _last* variable changes during layout process)
319 vChild._recomputeBoxWidth();
321 // wrong: simple invalidates are enough here
322 // correct: needs recompute to inform children (to update centering for example)
323 vChild._recomputeOuterWidth();
324 vChild._recomputeInnerWidth();
326 // apply calculated width
327 vChild._applyRuntimeWidth(vChild.getBoxWidth());
330 qx.Proto._applyComputedHeight = function(vChild)
332 // direct recompute (need to be done, while layouting as the
333 // _last* variable changes during layout process)
334 vChild._recomputeBoxHeight();
336 // wrong: simple invalidates are enough here
337 // correct: needs recompute to inform children (to update centering for example)
338 vChild._recomputeOuterHeight();
339 vChild._recomputeInnerHeight();
341 // apply calculated height
342 vChild._applyRuntimeHeight(vChild.getBoxHeight());
345 qx.Proto.layoutChild_sizeX = function(vChild, vJobs)
347 // We need to respect all dimension properties on the horizontal axis in internet explorer to set the 'width' style
348 if (vJobs.initial || vJobs.width || vJobs.minWidth || vJobs.maxWidth) {
349 vChild._computedWidthTypeNull && vChild._computedMinWidthTypeNull && vChild._computedMaxWidthTypeNull ? vChild._resetRuntimeWidth() : vChild._applyRuntimeWidth(vChild.getBoxWidth());
353 qx.Proto.layoutChild_sizeY = function(vChild, vJobs)
355 // We need to respect all dimension properties on the vertical axis in internet explorer to set the 'height' style
356 if (vJobs.initial || vJobs.height || vJobs.minHeight || vJobs.maxHeight) {
357 vChild._computedHeightTypeNull && vChild._computedMinHeightTypeNull && vChild._computedMaxHeightTypeNull ? vChild._resetRuntimeHeight() : vChild._applyRuntimeHeight(vChild.getBoxHeight());
361 qx.Proto.layoutChild_location_horizontal = function(vChild) {
362 this._applyComputedWidth(vChild);
365 qx.Proto.layoutChild_location_vertical = function(vChild) {
366 this._applyComputedHeight(vChild);
369 qx.Proto.layoutChild_location_right = function(vChild, vJobs)
371 vChild._applyRuntimeLeft(this.getWidget().getInnerWidth() - this._lastRight - vChild.getBoxWidth());
372 vChild._applyRuntimeTop(this._lastTop);
374 this.layoutChild_location_vertical(vChild);
376 this._lastRight += vChild.getBoxWidth();
379 qx.Proto.layoutChild_location_bottom = function(vChild, vJobs)
381 vChild._applyRuntimeTop(this.getWidget().getInnerHeight() - this._lastBottom - vChild.getBoxHeight());
382 vChild._applyRuntimeLeft(this._lastLeft);
384 this.layoutChild_location_horizontal(vChild);
386 this._lastBottom += vChild.getBoxHeight();
389 qx.Proto.layoutChild_location_default = function(vChild, vJobs)
391 var vWidget = this.getWidget();
393 vChild._resetRuntimeRight();
394 vChild._resetRuntimeBottom();
396 vChild._applyRuntimeTop(this._lastTop);
397 vChild._applyRuntimeLeft(this._lastLeft);
399 this._applyComputedWidth(vChild);
400 this._applyComputedHeight(vChild);
405 qx.Proto._applyComputedWidth = function(vChild)
407 // direct recompute (need to be done, while layouting as the
408 // _last* variable changes during layout process)
409 vChild._recomputeBoxWidth();
411 // wrong: simple invalidates are enough here
412 // correct: needs recompute to inform children (to update centering for example)
413 vChild._recomputeOuterWidth();
414 vChild._recomputeInnerWidth();
417 qx.Proto._applyComputedHeight = function(vChild)
419 // direct recompute (need to be done, while layouting as the
420 // _last* variable changes during layout process)
421 vChild._recomputeBoxHeight();
423 // wrong: simple invalidates are enough here
424 // correct: needs recompute to inform children (to update centering for example)
425 vChild._recomputeOuterHeight();
426 vChild._recomputeInnerHeight();
429 qx.Proto.layoutChild_sizeX = function(vChild, vJobs)
431 if (vJobs.initial || vJobs.width) {
432 vChild._computedWidthTypeNull ? vChild._resetRuntimeWidth() : vChild._applyRuntimeWidth(vChild.getWidthValue());
436 qx.Proto.layoutChild_sizeY = function(vChild, vJobs)
438 if (vJobs.initial || vJobs.height) {
439 vChild._computedHeightTypeNull ? vChild._resetRuntimeHeight() : vChild._applyRuntimeHeight(vChild.getHeightValue());
443 qx.Proto.layoutChild_location_horizontal = function(vChild)
445 this._applyComputedWidth(vChild);
446 vChild._applyRuntimeRight(this._lastRight);
449 qx.Proto.layoutChild_location_vertical = function(vChild)
451 this._applyComputedHeight(vChild);
452 vChild._applyRuntimeBottom(this._lastBottom);
455 qx.Proto.layoutChild_location_right = function(vChild, vJobs)
457 vChild._applyRuntimeRight(this._lastRight);
458 vChild._applyRuntimeTop(this._lastTop);
460 this.layoutChild_location_vertical(vChild);
462 this._lastRight += vChild.getBoxWidth();
465 qx.Proto.layoutChild_location_bottom = function(vChild, vJobs)
467 vChild._applyRuntimeBottom(this._lastBottom);
468 vChild._applyRuntimeLeft(this._lastLeft);
470 this.layoutChild_location_horizontal(vChild);
472 this._lastBottom += vChild.getBoxHeight();
475 qx.Proto.layoutChild_location_default = function(vChild, vJobs)
477 vChild._resetRuntimeWidth();
478 vChild._resetRuntimeHeight();
480 vChild._applyRuntimeTop(this._lastTop);
481 vChild._applyRuntimeRight(this._lastRight);
482 vChild._applyRuntimeBottom(this._lastBottom);
483 vChild._applyRuntimeLeft(this._lastLeft);
485 this._applyComputedWidth(vChild);
486 this._applyComputedHeight(vChild);