blob: 9fb9983d7ee4bc6adab8016da90ff3b6b5082482 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 1&1 Internet AG, Germany, http://www.1und1.de,
* EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* 1&1 Internet AG and others - original API and implementation
* EclipseSource - adaptation for the Eclipse Remote Application Platform
******************************************************************************/
/**
* Abstract base class for all widget which have child widgets (e.g. layout manager)
*
* Don't instantiate this class directly.
*/
rwt.qx.Class.define("rwt.widgets.base.Parent",
{
extend : rwt.widgets.base.Widget,
/*
*****************************************************************************
CONSTRUCTOR
*****************************************************************************
*/
construct : function()
{
this.base(arguments);
// Contains all children
this._children = [];
// Create instanceof layout implementation
this._layoutImpl = this._createLayoutImpl();
},
/*
*****************************************************************************
PROPERTIES
*****************************************************************************
*/
properties :
{
/** Individual focus handler for all child elements. */
focusHandler :
{
check : "rwt.widgets.util.FocusHandler",
apply : "_applyFocusHandler",
nullable : true
},
/** The current active child. */
activeChild :
{
check : "rwt.widgets.base.Widget",
event : "changeActiveChild",
nullable : true
},
/** The current focused child. */
focusedChild :
{
check : "rwt.widgets.base.Widget",
apply : "_applyFocusedChild",
event : "changeFocusedChild",
nullable : true
},
/** all visible child widgets */
visibleChildren :
{
_cached : true,
defaultValue : null
}
},
/*
*****************************************************************************
MEMBERS
*****************************************************************************
*/
members :
{
/*
---------------------------------------------------------------------------
FOCUS HANDLING
---------------------------------------------------------------------------
*/
/**
* Wether the widget has its own focus handler or uses one of its parent's
* focus handler.
*
* @type member
* @return {Boolean} whether the widget has its own focus handler
*/
isFocusRoot : function() {
return this.getFocusHandler() != null;
},
/**
* Return the responsible focus handler
*
* @type member
* @return {rwt.widgets.util.FocusHandler} TODOC
*/
getFocusRoot : function()
{
if (this.isFocusRoot()) {
return this;
}
if (this._hasParent) {
return this.getParent().getFocusRoot();
}
return null;
},
/**
* Let the widget use its own focus handler
*
* @type member
* @return {void}
*/
activateFocusRoot : function()
{
if (this._focusHandler) {
return;
}
this._focusHandler = new rwt.widgets.util.FocusHandler(this);
this.setFocusHandler(this._focusHandler);
},
/**
* Delegate keyevent to the focus handler
*
* @type member
* @param e {Event} TODOC
* @return {void}
*/
_onfocuskeyevent : function(e) {
this.getFocusHandler()._onkeyevent(this, e);
},
/**
* TODOC
*
* @type member
* @param value {var} Current value
* @param old {var} Previous value
*/
_applyFocusHandler : function(value)
{
if (value)
{
// Add Key Handler
this.addEventListener("keypress", this._onfocuskeyevent);
// Activate focus handling (but keep already configured tabIndex)
if (this.getTabIndex() < 1) {
this.setTabIndex(1);
}
// But hide the focus outline
this.setHideFocus(true);
// Make myself the default
this.setActiveChild(this);
}
else
{
// Remove Key Handler
this.removeEventListener("keydown", this._onfocuskeyevent);
this.removeEventListener("keypress", this._onfocuskeyevent);
// Deactivate focus handling
this.setTabIndex(null);
// Don't hide focus outline
this.setHideFocus(false);
}
},
/**
* TODOC
*
* @type member
* @param value {var} Current value
* @param old {var} Previous value
*/
_applyFocusedChild : function(value, old)
{
var vFocusValid = value != null;
var vBlurValid = old != null;
if (rwt.qx.Class.isDefined("rwt.widgets.util.PopupManager") && vFocusValid)
{
var vMgr = rwt.widgets.util.PopupManager.getInstance();
if (vMgr) {
vMgr.update(value);
}
}
if (vBlurValid)
{
// Dispatch FocusOut
if (old.hasEventListeners("focusout"))
{
var vEventObject = new rwt.event.FocusEvent("focusout", old);
if (vFocusValid) {
vEventObject.setRelatedTarget(value);
}
old.dispatchEvent(vEventObject);
vEventObject.dispose();
}
}
if (vFocusValid)
{
if (value.hasEventListeners("focusin"))
{
// Dispatch FocusIn
var vEventObject = new rwt.event.FocusEvent("focusin", value);
if (vBlurValid) {
vEventObject.setRelatedTarget(old);
}
value.dispatchEvent(vEventObject);
vEventObject.dispose();
}
}
if (vBlurValid)
{
if (this.getActiveChild() == old && !vFocusValid) {
this.setActiveChild(null);
}
old.setFocused(false);
// Dispatch Blur
var vEventObject = new rwt.event.FocusEvent("blur", old);
if (vFocusValid) {
vEventObject.setRelatedTarget(value);
}
old.dispatchEvent(vEventObject);
var vMgr = rwt.widgets.util.ToolTipManager.getInstance();
if (vMgr) {
vMgr.handleBlur(vEventObject);
}
vEventObject.dispose();
}
if (vFocusValid)
{
this.setActiveChild(value);
value.setFocused(true);
rwt.event.EventHandler.setFocusRoot(this);
// Dispatch Focus
var vEventObject = new rwt.event.FocusEvent("focus", value);
if (vBlurValid) {
vEventObject.setRelatedTarget(old);
}
value.dispatchEvent(vEventObject);
var vMgr = rwt.widgets.util.ToolTipManager.getInstance();
if (vMgr) {
vMgr.handleFocus(vEventObject);
}
vEventObject.dispose();
}
},
_applyWidth : function( newValue, oldValue ) {
this.base( arguments, newValue, oldValue );
this._layoutX();
},
_applyHeight : function( newValue, oldValue ) {
this.base( arguments, newValue, oldValue );
this._layoutY();
},
_applyBorder : function( newValue, oldValue ) {
this.base( arguments, newValue, oldValue );
this._layoutX();
this._layoutY();
},
_applyDirection : function( value ) {
this.base( arguments, value );
this._layoutX();
},
_layoutX : function() {},
_layoutY : function() {},
/*
---------------------------------------------------------------------------
LAYOUT IMPLEMENTATION
---------------------------------------------------------------------------
*/
_layoutImpl : null,
/**
* abstract method. Create layout implementation.
*
* This method must be overwritten by all subclasses
*
* return
*
* @type member
* @return {rwt.widgets.base.BoxLayout} TODOC
*/
_createLayoutImpl : function() {
return new rwt.widgets.util.CanvasLayoutImpl( this);
},
/**
* Return the layout implementation.
*
* return {rwt.widgets.util.LayoutImpl}
*
* @type member
* @return {var} TODOC
*/
getLayoutImpl : function() {
return this._layoutImpl;
},
/*
---------------------------------------------------------------------------
CHILDREN MANAGMENT: MANAGE ALL
---------------------------------------------------------------------------
*/
/**
* Return the array of all children
*
* @type member
* @return {rwt.widgets.base.Widget[]} all children
*/
getChildren : function() {
return this._children;
},
/**
* Get number of children
*
* @type member
* @return {Integer} number of children
*/
getChildrenLength : function() {
return this.getChildren().length;
},
/**
* Check if the widget has children
*
* @type member
* @return {Boolean} whether the widget has children
*/
hasChildren : function() {
return this.getChildrenLength() > 0;
},
/**
* Check if there are any children inside
*
* @type member
* @return {Boolean} whether the number of children is 0
*/
isEmpty : function() {
return this.getChildrenLength() === 0;
},
/**
* Get the index of a child widget.
*
* @type member
* @param vChild {rwt.widgets.base.Widget} Child widget to get the index for
* @return {Integer} index of the child widget
*/
indexOf : function(vChild) {
return this.getChildren().indexOf(vChild);
},
/**
* Check if the given widget is a child
*
* @type member
* @param vWidget {rwt.widgets.base.Widget} The widget which should be checked.
* @return {Boolean | var} TODOC
*/
contains : function(vWidget)
{
switch(vWidget)
{
case null:
return false;
case this:
return true;
default:
// try the next parent of the widget (recursive until found)
return this.contains(vWidget.getParent());
}
},
/*
---------------------------------------------------------------------------
CHILDREN MANAGMENT: MANAGE VISIBLE ONES
uses a cached private property
---------------------------------------------------------------------------
*/
/**
* Return the array of all visible children
* (which are configured as visible=true)
*
* @type member
* @return {rwt.widgets.base.Widget[]} all visible children
*/
_computeVisibleChildren : function()
{
var vVisible = [];
var vChildren = this.getChildren();
if (! vChildren)
{
return 0;
}
var vLength = vChildren.length;
for (var i=0; i<vLength; i++)
{
var vChild = vChildren[i];
if (vChild._isDisplayable ) {
vVisible.push(vChild);
}
}
return vVisible;
},
/**
* Get number of visible children
*
* @type member
* @return {Integer} number of visible children
*/
getVisibleChildrenLength : function() {
return this.getVisibleChildren().length;
},
/**
* Check if the widget has any visible children
*
* @type member
* @return {Boolean} whether the widget has any visible children
*/
hasVisibleChildren : function() {
return this.getVisibleChildrenLength() > 0;
},
/**
* Check whether there are any visible children inside
*
* @type member
* @return {Boolean} whether there are any visible children inside
*/
isVisibleEmpty : function() {
return this.getVisibleChildrenLength() === 0;
},
/*
---------------------------------------------------------------------------
CHILDREN MANAGMENT: ADD
---------------------------------------------------------------------------
*/
/**
* Add/Append another widget. Allows to add multiple at
* one, a parameter could be a widget.
*
* @type member
* @param varargs {rwt.widgets.base.Widget} variable number of widgets to add
* @return {Parent} This widget.
* @throws TODOC
*/
add : function()
{
var vWidget;
for (var i=0, l=arguments.length; i<l; i++)
{
vWidget = arguments[i];
vWidget.setParent( this );
}
return this;
},
/**
* Add a child widget at the specified index
*
* @type member
* @param vChild {widget} widget to add
* @param vIndex {Integer} Index, at which the widget will be inserted
*/
addAt : function(vChild, vIndex)
{
if (vIndex == null || vIndex < 0) {
throw new Error("Not a valid index for addAt(): " + vIndex);
}
if (vChild.getParent() == this)
{
var vChildren = this.getChildren();
var vOldIndex = vChildren.indexOf(vChild);
if (vOldIndex != vIndex)
{
if (vOldIndex != -1) {
rwt.util.Arrays.removeAt(vChildren, vOldIndex);
}
rwt.util.Arrays.insertAt(vChildren, vChild, vIndex);
if (this._initialLayoutDone)
{
this._invalidateVisibleChildren();
this.getLayoutImpl().updateChildrenOnMoveChild(vChild, vIndex, vOldIndex);
}
}
}
else
{
vChild._insertIndex = vIndex;
vChild.setParent(this);
}
},
/**
* Add a child widget as the first widget
*
* @type member
* @param vChild {widget} widget to add
*/
addAtBegin : function(vChild) {
return this.addAt(vChild, 0);
},
/**
* Add a child widget as the last widget
*
* @type member
* @param vChild {widget} widget to add
*/
addAtEnd : function(vChild)
{
// we need to fix here, when the child is already inside myself, but
// want to change its position
var vLength = this.getChildrenLength();
return this.addAt(vChild, vChild.getParent() == this ? vLength - 1 : vLength);
},
/**
* Add a widget before another already inserted widget
*
* @type member
* @param vChild {var} widget to add
* @param vBefore {var} widget before the new widget will be inserted.
*/
addBefore : function(vChild, vBefore)
{
var vChildren = this.getChildren();
var vTargetIndex = vChildren.indexOf(vBefore);
if (vTargetIndex == -1) {
throw new Error("Child to add before: " + vBefore + " is not inside this parent.");
}
var vSourceIndex = vChildren.indexOf(vChild);
if (vSourceIndex == -1 || vSourceIndex > vTargetIndex) {
vTargetIndex++;
}
return this.addAt(vChild, Math.max(0, vTargetIndex - 1));
},
/**
* Add a widget after another already inserted widget
*
* @type member
* @param vChild {var} widget to add
* @param vAfter {var} widgert, after which the new widget will be inserted
*/
addAfter : function(vChild, vAfter)
{
var vChildren = this.getChildren();
var vTargetIndex = vChildren.indexOf(vAfter);
if (vTargetIndex == -1) {
throw new Error("Child to add after: " + vAfter + " is not inside this parent.");
}
var vSourceIndex = vChildren.indexOf(vChild);
if (vSourceIndex != -1 && vSourceIndex < vTargetIndex) {
vTargetIndex--;
}
return this.addAt(vChild, Math.min(vChildren.length, vTargetIndex + 1));
},
/*
---------------------------------------------------------------------------
CHILDREN MANAGMENT: REMOVE
---------------------------------------------------------------------------
*/
/**
* Remove one or multiple childrens.
*
* @type member
* @param varargs {rwt.widgets.base.Widget} variable number of widgets to remove
*/
remove : function( /*children*/ )
{
var vWidget;
for (var i=0, l=arguments.length; i<l; i++)
{
vWidget = arguments[i];
if (!(vWidget instanceof rwt.widgets.base.Parent) && !(vWidget instanceof rwt.widgets.base.Terminator)) {
throw new Error("Invalid Widget: " + vWidget);
} else if (vWidget.getParent() == this) {
vWidget.setParent(null);
}
}
},
/**
* Remove the widget at the specified index.
*
* @type member
* @param vIndex {Integer} Index of the widget to remove.
*/
removeAt : function(vIndex)
{
var vChild = this.getChildren()[vIndex];
if (vChild)
{
delete vChild._insertIndex;
vChild.setParent(null);
}
},
/**
* Remove all children.
*
* @type member
*/
removeAll : function()
{
var cs = this.getChildren();
var co = cs[0];
while (co)
{
this.remove(co);
co = cs[0];
}
},
/*
---------------------------------------------------------------------------
CHILDREN MANAGMENT: FIRST CHILD
---------------------------------------------------------------------------
*/
/**
* Get the first child
*
* @type member
* @return {Widget|null} First child widget (null if this widget does not have any children)
*/
getFirstChild : function() {
return rwt.util.Arrays.getFirst(this.getChildren()) || null;
},
/**
* Get the first visible child
*
* @type member
* @return {Widget|null} First visible child widget (null if this widget does
* not have any visible children)
*/
getFirstVisibleChild : function() {
return rwt.util.Arrays.getFirst(this.getVisibleChildren()) || null;
},
/**
* Get the first active child
*
* @type member
* @param vIgnoreClasses {Class[]} array of classes which should be ignored
* @return {Widget|null} First active child widget (null if this widget does
* not have any active children)
*/
getFirstActiveChild : function(vIgnoreClasses) {
return rwt.widgets.base.Widget.getActiveSiblingHelper(null, this, 1, vIgnoreClasses, "first") || null;
},
/*
---------------------------------------------------------------------------
CHILDREN MANAGMENT: LAST CHILD
---------------------------------------------------------------------------
*/
/**
* Get the last child
*
* @type member
* @return {Widget|null} Last child widget (null if this widget does
* not have any children)
*/
getLastChild : function() {
return rwt.util.Arrays.getLast(this.getChildren()) || null;
},
/**
* Get the last visible child
*
* @type member
* @return {Widget|null} Last visible child widget (null if this widget does
* not have any visible children)
*/
getLastVisibleChild : function() {
return rwt.util.Arrays.getLast(this.getVisibleChildren()) || null;
},
/**
* Get the last active child
*
* @type member
* @param vIgnoreClasses {Class[]} array of classes which should be ignored
* @return {Widget|null} Last active child widget (null if this widget does
* not have any active children)
*/
getLastActiveChild : function(vIgnoreClasses) {
return rwt.widgets.base.Widget.getActiveSiblingHelper(null, this, -1, vIgnoreClasses, "last") || null;
},
/*
---------------------------------------------------------------------------
CHILDREN MANAGMENT: LOOP UTILS
---------------------------------------------------------------------------
*/
/**
* Call a callbach function for each child widget. The callback has the following signature:
* <code>function(childWidget, widgetIndex)</code>. The first parameter is the child widget
* and the second the index of the child widget in its parent.
*
* @type member
* @param vFunc {Function} callback function. Signature: <code>function(childWidget, widgetIndex)</code>
*/
forEachChild : function(vFunc)
{
var ch = this.getChildren(), chc, i = -1;
if (! ch) {
return;
}
chc = ch[++i];
while( chc ) {
vFunc.call(chc, i);
chc = ch[++i];
}
},
/**
* Call a callbach function for each visible child widget. The callback has the following signature:
* <code>function(childWidget, widgetIndex)</code>. The first parameter is the child widget
* and the second the index of the child widget in its parent.
*
* @type member
* @param vFunc {Function} callback function. Signature: <code>function(childWidget, widgetIndex)</code>
*/
forEachVisibleChild : function(vFunc)
{
var ch = this.getVisibleChildren(), chc, i = -1;
if (! ch) {
return;
}
chc = ch[++i];
while( chc ) {
vFunc.call(chc, i);
chc = ch[++i];
}
},
_markInDispose : function() {
this._isInGlobalDisposeQueue = true;
if( this.forEachChild ) {
this.forEachChild( arguments.callee );
}
},
// overridden
_fireBeforeDispose : function() {
this.base( arguments );
if( this.forEachChild ) {
this.forEachChild( arguments.callee );
}
},
/*
---------------------------------------------------------------------------
APPEAR/DISAPPEAR MESSAGES FOR CHILDREN
---------------------------------------------------------------------------
*/
// overridden
_beforeAppear : function()
{
this.base(arguments);
this.forEachVisibleChild(function()
{
if (this.isAppearRelevant()) {
this._beforeAppear();
}
});
},
// overridden
_afterAppear : function()
{
this.base(arguments);
this.forEachVisibleChild(function()
{
if (this.isAppearRelevant()) {
this._afterAppear();
}
});
},
// overridden
_beforeDisappear : function()
{
this.base(arguments);
this.forEachVisibleChild(function()
{
if (this.isAppearRelevant()) {
this._beforeDisappear();
}
});
},
// overridden
_afterDisappear : function()
{
this.base(arguments);
this.forEachVisibleChild(function()
{
if (this.isAppearRelevant()) {
this._afterDisappear();
}
});
},
// overridden
_afterInsertDom : function() {
this.base( arguments );
// NOTE: a "visible" Child is actually every "displayable" child here
this.forEachVisibleChild( function() {
// Check if the nodes are actually connected - See Bug 359665
if( this.getElement()
&& this.getElement().parentNode === this.getParent()._getTargetNode() )
{
this._afterInsertDom();
}
} );
},
// overridden
_afterRemoveDom : function() {
this.base( arguments );
this.forEachVisibleChild( function() {
if( this.isInDom() ) {
this._afterRemoveDom();
}
} );
},
/*
---------------------------------------------------------------------------
DISPLAYBLE HANDLING
---------------------------------------------------------------------------
*/
/**
* TODOC
*
* @type member
* @param vDisplayable {var} TODOC
* @param vParent {var} TODOC
* @param vHint {var} TODOC
* @return {void}
*/
_handleDisplayableCustom : function()
{
this.forEachChild(function() {
this._handleDisplayable();
});
},
/*
---------------------------------------------------------------------------
STATE QUEUE
---------------------------------------------------------------------------
*/
/**
* TODOC
*
* @type member
* @return {void}
*/
_addChildrenToStateQueue : function()
{
this.forEachVisibleChild(function() {
this.addToStateQueue();
});
},
// overridden
recursiveAddToStateQueue : function()
{
this.addToStateQueue();
this.forEachVisibleChild(function() {
this.recursiveAddToStateQueue();
});
},
// overridden
_recursiveAppearanceThemeUpdate : function(vNewAppearanceTheme, vOldAppearanceTheme)
{
this.base(arguments, vNewAppearanceTheme, vOldAppearanceTheme);
this.forEachVisibleChild(function() {
this._recursiveAppearanceThemeUpdate(vNewAppearanceTheme, vOldAppearanceTheme);
});
},
/*
---------------------------------------------------------------------------
CHILDREN QUEUE
---------------------------------------------------------------------------
*/
/**
* TODOC
*
* @type member
* @param vChild {var} TODOC
* @return {void}
*/
_addChildToChildrenQueue : function(vChild)
{
if (!vChild._isInParentChildrenQueue && vChild._isDisplayable)
{
rwt.widgets.base.Widget.addToGlobalLayoutQueue(this);
if (!this._childrenQueue) {
this._childrenQueue = {};
}
this._childrenQueue[vChild.toHashCode()] = vChild;
}
},
/**
* TODOC
*
* @type member
* @param vChild {var} TODOC
* @return {void}
*/
_removeChildFromChildrenQueue : function(vChild)
{
if (this._childrenQueue && vChild._isInParentChildrenQueue)
{
delete this._childrenQueue[vChild.toHashCode()];
if (rwt.util.Objects.isEmpty(this._childrenQueue))
{
this._childrenQueue = {};
rwt.widgets.base.Widget.removeFromGlobalLayoutQueue(this);
}
}
},
/**
* TODOC
*
* @type member
* @return {void}
*/
_flushChildrenQueue : function()
{
if (!rwt.util.Objects.isEmpty(this._childrenQueue))
{
this.getLayoutImpl().flushChildrenQueue(this._childrenQueue);
delete this._childrenQueue;
}
},
/*
---------------------------------------------------------------------------
LAYOUT QUEUE
---------------------------------------------------------------------------
*/
/**
* TODOC
*
* @type member
* @param p {var} TODOC
* @return {void}
*/
_addChildrenToLayoutQueue : function(p)
{
this.forEachChild(function() {
this.addToLayoutChanges(p);
});
},
/**
* TODOC
*
* @type member
* @param vChild {var} TODOC
* @return {void}
*/
_layoutChild : function(vChild)
{
if (!vChild._isDisplayable)
{
// this.warn("Want to render an invisible child: " + vChild + " -> omitting!");
return;
}
// APPLY LAYOUT
var vChanges = vChild._layoutChanges;
if (vChild.renderBorder && vChanges.border ) {
vChild.renderBorder( vChanges );
}
if (vChild.renderPadding)
{
if (vChanges.paddingLeft || vChanges.paddingRight || vChanges.paddingTop || vChanges.paddingBottom) {
vChild.renderPadding(vChanges);
}
}
// WRAP TO LAYOUT ENGINE
this.getLayoutImpl().layoutChild(vChild, vChanges);
// POST LAYOUT
vChild._layoutPost(vChanges);
// DISPLAY DOM NODE
// insert dom node (if initial flag enabled)
if (vChanges.initial)
{
vChild._initialLayoutDone = true;
rwt.widgets.base.Widget.addToGlobalDisplayQueue(vChild);
}
// CLEANUP
vChild._layoutChanges = {};
delete vChild._isInParentLayoutQueue;
delete this._childrenQueue[vChild.toHashCode()];
},
_layoutPost : function( changes ) {
this.createDispatchDataEvent( "flush", changes );
},
/*
---------------------------------------------------------------------------
DIMENSION CACHE
---------------------------------------------------------------------------
*/
/**
* TODOC
*
* @type member
* @return {var} TODOC
*/
_computePreferredInnerWidth : function() {
return this.getLayoutImpl().computeChildrenNeededWidth();
},
/**
* TODOC
*
* @type member
* @return {var} TODOC
*/
_computePreferredInnerHeight : function() {
return this.getLayoutImpl().computeChildrenNeededHeight();
},
/**
* TODOC
*
* @type member
* @param vNew {var} TODOC
* @param vOld {var} TODOC
* @return {void}
*/
_changeInnerWidth : function()
{
var vLayout = this.getLayoutImpl();
if (vLayout.invalidateChildrenFlexWidth) {
vLayout.invalidateChildrenFlexWidth();
}
this.forEachVisibleChild(function()
{
if (vLayout.updateChildOnInnerWidthChange(this) && this._recomputeBoxWidth())
{
this._recomputeOuterWidth();
this._recomputeInnerWidth();
}
});
},
/**
* TODOC
*
* @type member
* @param vNew {var} TODOC
* @param vOld {var} TODOC
* @return {void}
*/
_changeInnerHeight : function()
{
var vLayout = this.getLayoutImpl();
if (vLayout.invalidateChildrenFlexHeight) {
vLayout.invalidateChildrenFlexHeight();
}
this.forEachVisibleChild(function()
{
if (vLayout.updateChildOnInnerHeightChange(this) && this._recomputeBoxHeight())
{
this._recomputeOuterHeight();
this._recomputeInnerHeight();
}
});
},
/**
* TODOC
*
* @type member
* @param vChild {var} TODOC
* @return {var} TODOC
*/
getInnerWidthForChild : function() {
return this.getInnerWidth();
},
/**
* TODOC
*
* @type member
* @param vChild {var} TODOC
* @return {var} TODOC
*/
getInnerHeightForChild : function() {
return this.getInnerHeight();
},
/*
---------------------------------------------------------------------------
REMAPPING
---------------------------------------------------------------------------
*/
_remappingChildTable : [ "add", "remove", "addAt", "addAtBegin", "addAtEnd", "removeAt", "addBefore", "addAfter", "removeAll" ],
_remapStart : "return this._remappingChildTarget.",
_remapStop : ".apply(this._remappingChildTarget, arguments)",
/**
* TODOC
*
* @type member
* @param vTarget {var} TODOC
* @return {void}
*/
remapChildrenHandlingTo : function(vTarget)
{
var t = this._remappingChildTable;
this._remappingChildTarget = vTarget;
for (var i=0, l=t.length, s; i<l; i++)
{
s = t[i];
this[s] = new Function(rwt.widgets.base.Parent.prototype._remapStart + s + rwt.widgets.base.Parent.prototype._remapStop);
}
}
},
/*
*****************************************************************************
DESTRUCTOR
*****************************************************************************
*/
destruct : function()
{
this._disposeObjectDeep("_children", 1);
this._disposeObjects("_layoutImpl", "_focusHandler");
this._disposeFields("_childrenQueue", "_childrenQueue", "_remappingChildTable",
"_remappingChildTarget", "_cachedVisibleChildren");
}
});