summaryrefslogtreecommitdiff
path: root/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/core/Widget.js
diff options
context:
space:
mode:
Diffstat (limited to 'webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/core/Widget.js')
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/core/Widget.js5703
1 files changed, 5703 insertions, 0 deletions
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/core/Widget.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/core/Widget.js
new file mode 100644
index 0000000000..de775ac97b
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/core/Widget.js
@@ -0,0 +1,5703 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(ui_core)
+#require(qx.renderer.color.ColorCache)
+#require(qx.renderer.border.BorderCache)
+#require(qx.manager.object.AppearanceManager)
+#after(qx.component.init.InterfaceInitComponent)
+#optional(qx.ui.core.Parent)
+#optional(qx.ui.form.Button)
+#optional(qx.client.Timer)
+#optional(qx.client.Command)
+#optional(qx.ui.popup.ToolTip)
+#optional(qx.ui.menu.Menu)
+#optional(qx.ui.basic.Inline)
+
+************************************************************************ */
+
+/**
+ * This is the main widget, all visible objects in the application extend this.
+ *
+ * @event beforeAppear {qx.event.type.Event}
+ * @event appear {qx.event.type.Event}
+ * @event beforeDisappear {qx.event.type.Event}
+ * @event disappear {qx.event.type.Event}
+ * @event beforeInsertDom {qx.event.type.Event}
+ * @event insertDom {qx.event.type.Event}
+ * @event beforeRemoveDom {qx.event.type.Event}
+ * @event removeDom {qx.event.type.Event}
+ * @event create {qx.event.type.Event}
+ * @event execute {qx.event.type.Event}
+ * @event FADE_FINISHED {qx.event.type.DataEvent}
+ * @event mouseover {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event mousemove {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event mouseout {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event mousedown {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event mouseup {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event mousewheel {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event click {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event dblclick {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event contextmenu {qx.event.type.MouseEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event keydown {qx.event.type.KeyEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event keypress {qx.event.type.KeyEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event keyinput {qx.event.type.KeyEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event keyup {qx.event.type.KeyEvent} (Fired by {@link qx.event.handler.EventHandler})
+ * @event focusout {qx.event.type.FocusEvent} (Fired by {@link qx.ui.core.Parent})
+ * @event focusin {qx.event.type.FocusEvent} (Fired by {@link qx.ui.core.Parent})
+ * @event blur {qx.event.type.FocusEvent} (Fired by {@link qx.ui.core.Parent})
+ * @event focus {qx.event.type.FocusEvent} (Fired by {@link qx.ui.core.Parent})
+ */
+qx.OO.defineClass("qx.ui.core.Widget", qx.core.Target,
+function()
+{
+ if (this.classname == qx.ui.core.Widget.ABSTRACT_CLASS) {
+ throw new Error("Please omit the usage of qx.ui.core.Widget directly. Choose between qx.ui.core.Parent and qx.ui.basic.Terminator instead!");
+ }
+
+ qx.core.Target.call(this, true);
+
+
+ // ************************************************************************
+ // HTML MAPPING DATA STRUCTURES
+ // ************************************************************************
+ // Allows the user to setup styles and attributes without a
+ // need to have the target element created already.
+ /*
+ this._htmlProperties = { className : this.classname }
+ this._htmlAttributes = { qxhashcode : this._hashCode }
+ */
+ this._styleProperties = { position : "absolute" }
+
+
+ // ************************************************************************
+ // LAYOUT CHANGES
+ // ************************************************************************
+ this._layoutChanges = {};
+
+
+ // ************************************************************************
+ // APPEARANCE
+ // ************************************************************************
+ this._states = {};
+ this._applyInitialAppearance();
+});
+
+qx.Class.ABSTRACT_CLASS = "qx.ui.core.Widget";
+
+// Will be calculated later (TODO: Move to qx.Dom?)
+qx.Class.SCROLLBAR_SIZE = 16;
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DEFAULT SETTINGS
+---------------------------------------------------------------------------
+*/
+
+qx.Settings.setDefault("enableQueueDebug", false);
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ BASIC PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ The parent widget (the real object, no ID or something)
+*/
+qx.OO.addProperty({ name : "parent", type : "object", instance : "qx.ui.core.Parent", defaultValue : null });
+
+/*!
+ The element node (if the widget is created, otherwise null)
+*/
+qx.OO.addProperty({ name : "element" });
+
+/*!
+ Simple and fast switch of the visibility of a widget.
+*/
+qx.OO.addProperty({ name : "visibility", type : "boolean", defaultValue : true });
+
+/*!
+ If the widget should be displayed. Use this property instead of visibility if the change
+ in visibility should have effects on the parent widget.
+*/
+qx.OO.addProperty({ name : "display", type : "boolean", defaultValue : true });
+
+/*!
+ If you switch this to true, the widget doesn't handle
+ events directly. It will redirect them to the parent
+ widget.
+*/
+qx.OO.addProperty({ name : "anonymous", type : "boolean", defaultValue : false, getAlias : "isAnonymous" });
+
+/*!
+ The tagname of the element which should automatically be created
+*/
+qx.OO.addProperty({ name : "tagName", type : "string", defaultValue : "div" });
+
+/*!
+ This is used by many layout managers to control the individual horizontal alignment of this widget inside this parent.
+
+ This should be used with caution since in some cases
+ this might give unrespected results.
+*/
+qx.OO.addProperty({ name : "horizontalAlign", type : "string" });
+
+/*!
+ This is used by many layout managers to control the individual vertical alignment of this widget inside this parent.
+
+ This should be used with caution since in some cases
+ this might give unrespected results.
+*/
+qx.OO.addProperty({ name : "verticalAlign", type : "string" });
+
+/*!
+ Should this widget be stretched on the x-axis if the layout handler will do this?
+ Used by some layout handlers (qx.ui.layout.BoxLayout, ...).
+*/
+qx.OO.addProperty({ name : "allowStretchX", type : "boolean", defaultValue : true });
+
+/*!
+ Should this widget be stretched on the y-axis if the layout handler will do this?
+ Used by some layout handlers (qx.ui.layout.BoxLayout, ...).
+*/
+qx.OO.addProperty({ name : "allowStretchY", type : "boolean", defaultValue : true });
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ STYLE PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ Mapping to native style property z-index.
+
+ This should be used with caution since in some cases
+ this might give unrespected results.
+*/
+qx.OO.addProperty({ name : "zIndex", type : "number" });
+
+/*!
+ The backgroundColor style property of the rendered widget.
+ As input are allowed any instance of qx.renderer.color.Color or a string which defines the color itself.
+*/
+qx.OO.addProperty({ name : "backgroundColor", type : "object", instance : "qx.renderer.color.Color", convert : qx.renderer.color.ColorCache, allowMultipleArguments : true });
+
+/*!
+ The color style property of the rendered widget.
+ As input are allowed any instance of qx.renderer.color.Color or a string which defines the color itself.
+*/
+qx.OO.addProperty({ name : "color", type : "object", instance : "qx.renderer.color.Color", convert : qx.renderer.color.ColorCache, allowMultipleArguments : true });
+
+/*!
+ The border property describes how to paint the border on the widget.
+
+ This should be used with caution since in some cases (mostly complex widgets)
+ this might give unrespected results.
+*/
+qx.OO.addProperty({ name : "border", type : "object", instance : "qx.renderer.border.Border", convert : qx.renderer.border.BorderCache, allowMultipleArguments : true });
+
+/*!
+ Mapping to native style property opacity.
+
+ The uniform opacity setting to be applied across an entire object. Behaves like the new CSS-3 Property.
+ Any values outside the range 0.0 (fully transparent) to 1.0 (fully opaque) will be clamped to this range.
+*/
+qx.OO.addProperty({ name : "opacity", type : "number" });
+
+/*!
+ Mapping to native style property cursor.
+
+ The name of the cursor to show when the mouse pointer is over the widget.
+ This is any valid CSS2 cursor name defined by W3C.
+
+ The following values are possible:
+ <ul><li>default</li>
+ <li>crosshair</li>
+ <li>pointer (hand is the ie name and will mapped to pointer in non-ie).</li>
+ <li>move</li>
+ <li>n-resize</li>
+ <li>ne-resize</li>
+ <li>e-resize</li>
+ <li>se-resize</li>
+ <li>s-resize</li>
+ <li>sw-resize</li>
+ <li>w-resize</li>
+ <li>nw-resize</li>
+ <li>text</li>
+ <li>wait</li>
+ <li>help </li>
+ <li>url([file]) = self defined cursor, file should be an ANI- or CUR-type</li>
+ </ul>
+*/
+qx.OO.addProperty({ name : "cursor", type : "string" });
+
+/*!
+ Mapping to native style property background-image.
+
+ The URI of the image file to use as background image.
+*/
+qx.OO.addProperty({ name : "backgroundImage", type : "string" });
+
+/**
+ * Describes how to handle content that is too large to fit inside the widget.
+ *
+ * Overflow modes:
+ * * hidden: The content is clipped
+ * * auto: Scroll bars are shown as needed
+ * * scroll: Scroll bars are always shown. Even if there is enough room for the content inside the widget.
+ * * scrollX: Scroll bars for the X-Axis are always shown. Even if there is enough room for the content inside the widget.
+ * * scrollY: Scroll bars for the Y-Axis are always shown. Even if there is enough room for the content inside the widget.
+ */
+qx.OO.addProperty({ name : "overflow", type : "string", addToQueue : true });
+
+/*!
+ Clipping of the widget (left)
+*/
+qx.OO.addProperty({ name : "clipLeft", type : "number", impl : "clip" });
+
+/*!
+ Clipping of the widget (top)
+*/
+qx.OO.addProperty({ name : "clipTop", type : "number", impl : "clip" });
+
+/*!
+ Clipping of the widget (width)
+*/
+qx.OO.addProperty({ name : "clipWidth", type : "number", impl : "clip" });
+
+/*!
+ Clipping of the widget (height)
+*/
+qx.OO.addProperty({ name : "clipHeight", type : "number", impl : "clip" });
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ MANAGMENT PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ Set this to a positive value makes the widget able to get the focus.
+ It even is reachable through the usage of the tab-key.
+
+ Widgets with the same tabIndex are handled through there position
+ in the document.
+*/
+qx.OO.addProperty({ name : "tabIndex", type : "number", defaultValue : -1 });
+
+/*!
+ If the focus outline should be hidden.
+*/
+qx.OO.addProperty({ name : "hideFocus", type : "boolean", defaultValue : false });
+
+/*!
+ Use DOM focussing (focus() and blur() methods of DOM nodes)
+*/
+qx.OO.addProperty({ name : "enableElementFocus", type : "boolean", defaultValue : true });
+
+/*!
+ Handle focus state of this widget.
+
+ someWidget.setFocused(true) set the current focus to this widget.
+ someWidget.setFocused(false) remove the current focus and leave it blank.
+
+ Normally you didn't need to set this directly.
+*/
+qx.OO.addProperty({ name : "focused", type : "boolean", defaultValue : false });
+
+/*!
+ Toggle the possibility to select the element of this widget.
+*/
+qx.OO.addProperty({ name : "selectable", type : "boolean", defaultValue : true, getAlias : "isSelectable" });
+
+/*!
+ Contains the tooltip object connected to the widget.
+*/
+qx.OO.addProperty({ name : "toolTip", type : "object", instance : "qx.ui.popup.ToolTip" });
+
+/*!
+ Contains the context menu object connected to the widget. (Need real implementation)
+*/
+qx.OO.addProperty({ name : "contextMenu", type : "object", instance : "qx.ui.menu.Menu" });
+
+/*!
+ Capture all events and map them to this widget
+*/
+qx.OO.addProperty({ name : "capture", type : "boolean", defaultValue : false });
+
+/*!
+ Contains the support drop types for drag and drop support
+*/
+qx.OO.addProperty({ name : "dropDataTypes" });
+
+/*!
+ A command called if the widget should be excecuted (a placeholder for buttons, ...)
+*/
+qx.OO.addProperty({ name : "command", type : "object", instance : "qx.client.Command" });
+
+/*!
+ Appearance of the widget
+*/
+qx.OO.addProperty({ name : "appearance", type : "string" });
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ MARGIN/PADDING PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ Margin of the widget (top)
+*/
+qx.OO.addProperty({ name : "marginTop", type : "number", addToQueue : true, impl : "marginY" });
+
+/*!
+ Margin of the widget (right)
+*/
+qx.OO.addProperty({ name : "marginRight", type : "number", addToQueue : true, impl : "marginX" });
+
+/*!
+ Margin of the widget (bottom)
+*/
+qx.OO.addProperty({ name : "marginBottom", type : "number", addToQueue : true, impl : "marginY" });
+
+/*!
+ Margin of the widget (left)
+*/
+qx.OO.addProperty({ name : "marginLeft", type : "number", addToQueue : true, impl : "marginX" });
+
+
+/*!
+ Padding of the widget (top)
+*/
+qx.OO.addProperty({ name : "paddingTop", type : "number", addToQueue : true, impl : "paddingY" });
+
+/*!
+ Padding of the widget (right)
+*/
+qx.OO.addProperty({ name : "paddingRight", type : "number", addToQueue : true, impl : "paddingX" });
+
+/*!
+ Padding of the widget (bottom)
+*/
+qx.OO.addProperty({ name : "paddingBottom", type : "number", addToQueue : true, impl : "paddingY" });
+
+/*!
+ Padding of the widget (left)
+*/
+qx.OO.addProperty({ name : "paddingLeft", type : "number", addToQueue : true, impl : "paddingX" });
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ HORIZONAL DIMENSION PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ The distance from the outer left border to the parent left area edge.
+
+ You could only set two of the three horizonal dimension properties (boxLeft, boxRight, boxWidth)
+ at the same time. This will be omitted during the setup of the new third value. To reset a value
+ you didn't want anymore, set it to null.
+*/
+qx.OO.addProperty({ name : "left", addToQueue : true, unitDetection : "pixelPercent" });
+
+/*!
+ The distance from the outer right border to the parent right area edge.
+
+ You could only set two of the three horizonal dimension properties (boxLeft, boxRight, boxWidth)
+ at the same time. This will be omitted during the setup of the new third value. To reset a value
+ you didn't want anymore, set it to null.
+*/
+qx.OO.addProperty({ name : "right", addToQueue : true, unitDetection : "pixelPercent" });
+
+/*!
+ The width of the box (including padding and border).
+
+ You could only set two of the three horizonal dimension properties (boxLeft, boxRight, boxWidth)
+ at the same time. This will be omitted during the setup of the new third value. To reset a value
+ you didn't want anymore, set it to null.
+*/
+qx.OO.addProperty({ name : "width", addToQueue : true, unitDetection : "pixelPercentAutoFlex" });
+
+/*!
+ The minimum width of the box (including padding and border).
+
+ Set this to omit the shrinking of the box width under this value.
+*/
+qx.OO.addProperty({ name : "minWidth", addToQueue : true, unitDetection : "pixelPercentAuto" });
+
+/*!
+ The maximum width of the box (including padding and border).
+
+ Set this to omit the expanding of the box width above this value.
+*/
+qx.OO.addProperty({ name : "maxWidth", addToQueue : true, unitDetection : "pixelPercentAuto" });
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ VERTICAL DIMENSION PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ The distance from the outer top border to the parent top area edge.
+
+ You could only set two of the three vertical dimension properties (boxTop, boxBottom, boxHeight)
+ at the same time. This will be omitted during the setup of the new third value. To reset a value
+ you didn't want anymore, set it to null.
+*/
+qx.OO.addProperty({ name : "top", addToQueue : true, unitDetection : "pixelPercent" });
+
+/*!
+ The distance from the outer bottom border to the parent bottom area edge.
+
+ You could only set two of the three vertical dimension properties (boxTop, boxBottom, boxHeight)
+ at the same time. This will be omitted during the setup of the new third value. To reset a value
+ you didn't want anymore, set it to null.
+*/
+qx.OO.addProperty({ name : "bottom", addToQueue : true, unitDetection : "pixelPercent" });
+
+/*!
+ The height of the box (including padding and border).
+
+ You could only set two of the three vertical dimension properties (boxTop, boxBottom, boxHeight)
+ at the same time. This will be omitted during the setup of the new third value. To reset a value
+ you didn't want anymore, set it to null.
+*/
+qx.OO.addProperty({ name : "height", addToQueue : true, unitDetection : "pixelPercentAutoFlex" });
+
+/*!
+ The minimum height of the box (including padding and border).
+
+ Set this to omit the shrinking of the box height under this value.
+*/
+qx.OO.addProperty({ name : "minHeight", addToQueue : true, unitDetection : "pixelPercentAuto" });
+
+/*!
+ The maximum height of the box (including padding and border).
+
+ Set this to omit the expanding of the box height above this value.
+*/
+qx.OO.addProperty({ name : "maxHeight", addToQueue : true, unitDetection : "pixelPercentAuto" });
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ PROPERTY GROUPS
+---------------------------------------------------------------------------
+*/
+
+qx.OO.addPropertyGroup({ name : "location", members : [ "left", "top" ]});
+qx.OO.addPropertyGroup({ name : "dimension", members : [ "width", "height" ]});
+
+qx.OO.addPropertyGroup({ name : "space", members : [ "left", "width", "top", "height" ]});
+qx.OO.addPropertyGroup({ name : "edge", members : [ "top", "right", "bottom", "left" ], mode : "shorthand" });
+
+qx.OO.addPropertyGroup({ name : "padding", members : [ "paddingTop", "paddingRight", "paddingBottom", "paddingLeft" ], mode: "shorthand" });
+qx.OO.addPropertyGroup({ name : "margin", members : [ "marginTop", "marginRight", "marginBottom", "marginLeft" ], mode: "shorthand" });
+
+qx.OO.addPropertyGroup({ name : "heights", members : [ "minHeight", "height", "maxHeight" ]});
+qx.OO.addPropertyGroup({ name : "widths", members : [ "minWidth", "width", "maxWidth" ]});
+
+qx.OO.addPropertyGroup({ name : "align", members : [ "horizontalAlign", "verticalAlign" ]});
+qx.OO.addPropertyGroup({ name : "stretch", members : [ "stretchX", "stretchY" ]});
+
+qx.OO.addPropertyGroup({ name : "clipLocation", members : [ "clipLeft", "clipTop" ]});
+qx.OO.addPropertyGroup({ name : "clipDimension", members : [ "clipWidth", "clipHeight" ]});
+qx.OO.addPropertyGroup({ name : "clip", members : [ "clipLeft", "clipTop", "clipWidth", "clipHeight" ]});
+
+
+
+
+
+
+
+
+/* ************************************************************************
+ Class data, properties and methods
+************************************************************************ */
+
+/*
+---------------------------------------------------------------------------
+ ALL QUEUES
+---------------------------------------------------------------------------
+*/
+
+if (qx.Settings.getValueOfClass("qx.ui.core.Widget", "enableQueueDebug"))
+{
+ qx.ui.core.Widget.flushGlobalQueues = function()
+ {
+ if (qx.ui.core.Widget._inFlushGlobalQueues || !qx.core.Init.getInstance().getComponent().isUiReady()) {
+ return;
+ }
+
+ if (!(qx.ui.core.Widget._globalWidgetQueue.length > 0 || qx.ui.core.Widget._globalElementQueue.length > 0 ||
+ qx.ui.core.Widget._globalStateQueue.length > 0 || qx.ui.core.Widget._globalJobQueue.length > 0 ||
+ qx.ui.core.Widget._globalLayoutQueue.length > 0 || qx.ui.core.Widget._fastGlobalDisplayQueue.length > 0 ||
+ !qx.lang.Object.isEmpty(qx.ui.core.Widget._lazyGlobalDisplayQueue))) {
+ return;
+ }
+
+ var globalWidgetQueueLength = qx.ui.core.Widget._globalWidgetQueue.length;
+ var globalElementQueueLength = qx.ui.core.Widget._globalElementQueue.length;
+ var globalStateQueueLength = qx.ui.core.Widget._globalStateQueue.length;
+ var globalJobQueueLength = qx.ui.core.Widget._globalJobQueue.length;
+ var globalLayoutQueueLength = qx.ui.core.Widget._globalLayoutQueue.length;
+ var fastGlobalDisplayQueueLength = qx.ui.core.Widget._fastGlobalDisplayQueue.length;
+ var lazyGlobalDisplayQueueLength = qx.ui.core.Widget._lazyGlobalDisplayQueue ? qx.ui.core.Widget._lazyGlobalDisplayQueue.length : 0;
+
+ // Also used for inline event handling to seperate 'real' events
+ qx.ui.core.Widget._inFlushGlobalQueues = true;
+
+ var vStart;
+
+ vStart = (new Date).valueOf();
+ qx.ui.core.Widget.flushGlobalWidgetQueue();
+ var vWidgetDuration = (new Date).valueOf() - vStart;
+
+ vStart = (new Date).valueOf();
+ qx.ui.core.Widget.flushGlobalStateQueue();
+ var vStateDuration = (new Date).valueOf() - vStart;
+
+ vStart = (new Date).valueOf();
+ qx.ui.core.Widget.flushGlobalElementQueue();
+ var vElementDuration = (new Date).valueOf() - vStart;
+
+ vStart = (new Date).valueOf();
+ qx.ui.core.Widget.flushGlobalJobQueue();
+ var vJobDuration = (new Date).valueOf() - vStart;
+
+ vStart = (new Date).valueOf();
+ qx.ui.core.Widget.flushGlobalLayoutQueue();
+ var vLayoutDuration = (new Date).valueOf() - vStart;
+
+ vStart = (new Date).valueOf();
+ qx.ui.core.Widget.flushGlobalDisplayQueue();
+ var vDisplayDuration = (new Date).valueOf() - vStart;
+
+ var vSum = vWidgetDuration + vStateDuration + vElementDuration + vJobDuration + vLayoutDuration + vDisplayDuration;
+
+ if (vSum > 0)
+ {
+ var logger = qx.dev.log.Logger.getClassLogger(qx.ui.core.Widget);
+ logger.debug("Flush Global Queues");
+ logger.debug("Widgets: " + vWidgetDuration + "ms (" + globalWidgetQueueLength + ")");
+ logger.debug("State: " + vStateDuration + "ms (" + globalStateQueueLength + ")");
+ logger.debug("Element: " + vElementDuration + "ms (" + globalElementQueueLength + ")");
+ logger.debug("Job: " + vJobDuration + "ms (" + globalJobQueueLength + ")");
+ logger.debug("Layout: " + vLayoutDuration + "ms (" + globalLayoutQueueLength + ")");
+ logger.debug("Display: " + vDisplayDuration + "ms (fast:" + fastGlobalDisplayQueueLength + ",lazy:" + lazyGlobalDisplayQueueLength + ")");
+
+ window.status = "Flush: Widget:" + vWidgetDuration + " State:" + vStateDuration + " Element:" + vElementDuration + " Job:" + vJobDuration + " Layout:" + vLayoutDuration + " Display:" + vDisplayDuration;
+ }
+
+ delete qx.ui.core.Widget._inFlushGlobalQueues;
+ }
+}
+else
+{
+ qx.ui.core.Widget.flushGlobalQueues = function()
+ {
+ if (qx.ui.core.Widget._inFlushGlobalQueues || !qx.core.Init.getInstance().getComponent().isUiReady()) {
+ return;
+ }
+
+ // Also used for inline event handling to seperate 'real' events
+ qx.ui.core.Widget._inFlushGlobalQueues = true;
+
+ qx.ui.core.Widget.flushGlobalWidgetQueue();
+ qx.ui.core.Widget.flushGlobalStateQueue();
+ qx.ui.core.Widget.flushGlobalElementQueue();
+ qx.ui.core.Widget.flushGlobalJobQueue();
+ qx.ui.core.Widget.flushGlobalLayoutQueue();
+ qx.ui.core.Widget.flushGlobalDisplayQueue();
+
+ delete qx.ui.core.Widget._inFlushGlobalQueues;
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ WIDGET QUEUE
+
+ Allows widgets to register to the widget queue to do multiple things
+ before the other queues will be flushed
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget._globalWidgetQueue = [];
+
+qx.ui.core.Widget.addToGlobalWidgetQueue = function(vWidget)
+{
+ if (!vWidget._isInGlobalWidgetQueue && vWidget._isDisplayable)
+ {
+ qx.ui.core.Widget._globalWidgetQueue.push(vWidget);
+ vWidget._isInGlobalWidgetQueue = true;
+ }
+}
+
+qx.ui.core.Widget.removeFromGlobalWidgetQueue = function(vWidget)
+{
+ if (vWidget._isInGlobalWidgetQueue)
+ {
+ qx.lang.Array.remove(qx.ui.core.Widget._globalWidgetQueue, vWidget);
+ delete vWidget._isInGlobalWidgetQueue;
+ }
+}
+
+qx.ui.core.Widget.flushGlobalWidgetQueue = function()
+{
+ var vQueue=qx.ui.core.Widget._globalWidgetQueue, vLength, vWidget;
+
+ while ((vLength=vQueue.length) > 0)
+ {
+ for (var i=0; i<vLength; i++)
+ {
+ vWidget = vQueue[i];
+
+ vWidget.flushWidgetQueue();
+ delete vWidget._isInGlobalWidgetQueue;
+ }
+
+ vQueue.splice(0, vLength);
+ }
+}
+
+
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ ELEMENT QUEUE
+
+ Contains the widgets which should be (dom-)created
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget._globalElementQueue = [];
+
+qx.ui.core.Widget.addToGlobalElementQueue = function(vWidget)
+{
+ if (!vWidget._isInGlobalElementQueue && vWidget._isDisplayable)
+ {
+ qx.ui.core.Widget._globalElementQueue.push(vWidget);
+ vWidget._isInGlobalElementQueue = true;
+ }
+}
+
+qx.ui.core.Widget.removeFromGlobalElementQueue = function(vWidget)
+{
+ if (vWidget._isInGlobalElementQueue)
+ {
+ qx.lang.Array.remove(qx.ui.core.Widget._globalElementQueue, vWidget);
+ delete vWidget._isInGlobalElementQueue;
+ }
+}
+
+qx.ui.core.Widget.flushGlobalElementQueue = function()
+{
+ var vQueue=qx.ui.core.Widget._globalElementQueue, vLength, vWidget;
+
+ while ((vLength=vQueue.length) > 0)
+ {
+ for (var i=0; i<vLength; i++)
+ {
+ vWidget = vQueue[i];
+
+ vWidget._createElementImpl();
+ delete vWidget._isInGlobalElementQueue;
+ }
+
+ vQueue.splice(0, vLength);
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ STATE QUEUE
+
+ Contains the widgets which recently changed their state
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget._globalStateQueue = [];
+
+qx.ui.core.Widget.addToGlobalStateQueue = function(vWidget)
+{
+ if (!vWidget._isInGlobalStateQueue && vWidget._isDisplayable)
+ {
+ qx.ui.core.Widget._globalStateQueue.push(vWidget);
+ vWidget._isInGlobalStateQueue = true;
+ }
+}
+
+qx.ui.core.Widget.removeFromGlobalStateQueue = function(vWidget)
+{
+ if (vWidget._isInGlobalStateQueue)
+ {
+ qx.lang.Array.remove(qx.ui.core.Widget._globalStateQueue, vWidget);
+ delete vWidget._isInGlobalStateQueue;
+ }
+}
+
+qx.ui.core.Widget.flushGlobalStateQueue = function()
+{
+ var vQueue=qx.ui.core.Widget._globalStateQueue, vLength, vWidget;
+
+ while ((vLength=vQueue.length) > 0)
+ {
+ for (var i=0; i<vLength; i++)
+ {
+ vWidget = vQueue[i];
+
+ vWidget._applyStateAppearance();
+
+ delete vWidget._isInGlobalStateQueue;
+ }
+
+ vQueue.splice(0, vLength);
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ JOBS QUEUE
+
+ Contains the widgets which need a update after they were visible before
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget._globalJobQueue = [];
+
+qx.ui.core.Widget.addToGlobalJobQueue = function(vWidget)
+{
+ if (!vWidget._isInGlobalJobQueue && vWidget._isDisplayable)
+ {
+ qx.ui.core.Widget._globalJobQueue.push(vWidget);
+ vWidget._isInGlobalJobQueue = true;
+ }
+}
+
+qx.ui.core.Widget.removeFromGlobalJobQueue = function(vWidget)
+{
+ if (vWidget._isInGlobalJobQueue)
+ {
+ qx.lang.Array.remove(qx.ui.core.Widget._globalJobQueue, vWidget);
+ delete vWidget._isInGlobalJobQueue;
+ }
+}
+
+qx.ui.core.Widget.flushGlobalJobQueue = function()
+{
+ var vQueue=qx.ui.core.Widget._globalJobQueue, vLength, vWidget;
+
+ while ((vLength=vQueue.length) > 0)
+ {
+ for (var i=0; i<vLength; i++)
+ {
+ vWidget = vQueue[i];
+
+ vWidget._flushJobQueue(vWidget._jobQueue);
+ delete vWidget._isInGlobalJobQueue;
+ }
+
+ vQueue.splice(0, vLength);
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ LAYOUT QUEUE
+
+ Contains the parents (qx.ui.core.Parent) of the children which needs layout updates
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget._globalLayoutQueue = [];
+
+qx.ui.core.Widget.addToGlobalLayoutQueue = function(vParent)
+{
+ if (!vParent._isInGlobalLayoutQueue && vParent._isDisplayable)
+ {
+ qx.ui.core.Widget._globalLayoutQueue.push(vParent);
+ vParent._isInGlobalLayoutQueue = true;
+ }
+}
+
+qx.ui.core.Widget.removeFromGlobalLayoutQueue = function(vParent)
+{
+ if (vParent._isInGlobalLayoutQueue)
+ {
+ qx.lang.Array.remove(qx.ui.core.Widget._globalLayoutQueue, vParent);
+ delete vParent._isInGlobalLayoutQueue;
+ }
+}
+
+qx.ui.core.Widget.flushGlobalLayoutQueue = function()
+{
+ var vQueue=qx.ui.core.Widget._globalLayoutQueue, vLength, vParent;
+
+ while ((vLength=vQueue.length) > 0)
+ {
+ for (var i=0; i<vLength; i++)
+ {
+ vParent = vQueue[i];
+
+ vParent._flushChildrenQueue();
+ delete vParent._isInGlobalLayoutQueue;
+ }
+
+ vQueue.splice(0, vLength);
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPLAY QUEUE
+
+ Contains the widgets which should initially become visible
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget._fastGlobalDisplayQueue = [];
+qx.ui.core.Widget._lazyGlobalDisplayQueues = {};
+
+qx.ui.core.Widget.addToGlobalDisplayQueue = function(vWidget)
+{
+ if (!vWidget._isInGlobalDisplayQueue && vWidget._isDisplayable)
+ {
+ var vParent = vWidget.getParent();
+
+ if (vParent.isSeeable())
+ {
+ var vKey = vParent.toHashCode();
+
+ if (qx.ui.core.Widget._lazyGlobalDisplayQueues[vKey])
+ {
+ qx.ui.core.Widget._lazyGlobalDisplayQueues[vKey].push(vWidget);
+ }
+ else
+ {
+ qx.ui.core.Widget._lazyGlobalDisplayQueues[vKey] = [vWidget];
+ }
+ }
+ else
+ {
+ qx.ui.core.Widget._fastGlobalDisplayQueue.push(vWidget);
+ }
+
+ vWidget._isInGlobalDisplayQueue = true;
+ }
+}
+
+qx.ui.core.Widget.removeFromGlobalDisplayQueue = function(vWidget) {}
+
+qx.ui.core.Widget.flushGlobalDisplayQueue = function()
+{
+ var vKey, vLazyQueue, vWidget, vFragment;
+
+ var vFastQueue = qx.ui.core.Widget._fastGlobalDisplayQueue;
+ var vLazyQueues = qx.ui.core.Widget._lazyGlobalDisplayQueues;
+
+
+
+
+ /* -----------------------------------------------
+ Flush display queues
+ ----------------------------------------------- */
+
+ // Work on fast queue
+ for (var i=0, l=vFastQueue.length; i<l; i++)
+ {
+ vWidget = vFastQueue[i];
+ vWidget.getParent()._getTargetNode().appendChild(vWidget.getElement());
+ }
+
+
+ // Work on lazy queues: Inline widgets
+ if (qx.OO.isAvailable("qx.ui.basic.Inline"))
+ {
+ for (vKey in vLazyQueues)
+ {
+ vLazyQueue = vLazyQueues[vKey];
+
+ for (var i=0; i<vLazyQueue.length; i++)
+ {
+ vWidget = vLazyQueue[i];
+
+ if (vWidget instanceof qx.ui.basic.Inline)
+ {
+ vWidget._beforeInsertDom();
+
+ try
+ {
+ document.getElementById(vWidget.getInlineNodeId()).appendChild(vWidget.getElement());
+ }
+ catch(ex)
+ {
+ vWidget.debug("Could not append to inline id: " + vWidget.getInlineNodeId(), ex);
+ }
+
+ vWidget._afterInsertDom();
+ vWidget._afterAppear();
+
+ // Remove inline widget from queue and fix iterator position
+ qx.lang.Array.remove(vLazyQueue, vWidget);
+ i--;
+
+ // Reset display queue flag
+ delete vWidget._isInGlobalDisplayQueue;
+ }
+ }
+ }
+ }
+
+
+ // Work on lazy queues: Other widgets
+ for (vKey in vLazyQueues)
+ {
+ vLazyQueue = vLazyQueues[vKey];
+
+ // Speed enhancement: Choose a fairly small arbitrary value for the number
+ // of elements that should be added to the parent individually. If more
+ // than this number of elements is to be added to the parent, we'll create
+ // a document fragment, add the elements to the document fragment, and
+ // then add the whole fragment to the parent en mass (assuming that
+ // creation of a document fragment is supported by the browser).
+ if (document.createDocumentFragment && vLazyQueue.length >= 3)
+ {
+ // creating new document fragment
+ vFragment = document.createDocumentFragment();
+
+ // appending all widget elements to fragment
+ for (var i=0, l=vLazyQueue.length; i<l; i++)
+ {
+ vWidget = vLazyQueue[i];
+
+ vWidget._beforeInsertDom();
+ vFragment.appendChild(vWidget.getElement());
+ }
+
+ // append all fragment data at once to
+ // the already visible parent widget element
+ vLazyQueue[0].getParent()._getTargetNode().appendChild(vFragment);
+
+ for (var i=0, l=vLazyQueue.length; i<l; i++)
+ {
+ vWidget = vLazyQueue[i];
+ vWidget._afterInsertDom();
+ }
+ }
+ else
+ {
+ // appending all widget elements (including previously added children)
+ // to the already visible parent widget element
+ for (var i=0, l=vLazyQueue.length; i<l; i++)
+ {
+ vWidget = vLazyQueue[i];
+
+ vWidget._beforeInsertDom();
+ vWidget.getParent()._getTargetNode().appendChild(vWidget.getElement());
+ vWidget._afterInsertDom();
+ }
+ }
+ }
+
+
+
+
+
+
+ /* -----------------------------------------------
+ Cleanup and appear signals
+ ----------------------------------------------- */
+
+ // Only need to do this with the lazy queues
+ // because through the recursion from qx.ui.core.Parent
+ // all others get also informed.
+ for (vKey in vLazyQueues)
+ {
+ vLazyQueue = vLazyQueues[vKey];
+
+ for (var i=0, l=vLazyQueue.length; i<l; i++)
+ {
+ vWidget = vLazyQueue[i];
+
+ if (vWidget.getVisibility()) {
+ vWidget._afterAppear();
+ }
+
+ // Reset display queue flag
+ delete vWidget._isInGlobalDisplayQueue;
+ }
+
+ delete vLazyQueues[vKey];
+ }
+
+ // Reset display queue flag for widgets in fastQueue
+ for (var i=0, l=vFastQueue.length; i<l; i++) {
+ delete vFastQueue[i]._isInGlobalDisplayQueue;
+ }
+
+ // Remove fast queue entries
+ qx.lang.Array.removeAll(vFastQueue);
+}
+
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ GLOBAL HELPERS
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget.getActiveSiblingHelperIgnore = function(vIgnoreClasses, vInstance)
+{
+ for (var j=0; j<vIgnoreClasses.length; j++) {
+ if (vInstance instanceof vIgnoreClasses[j]) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+qx.ui.core.Widget.getActiveSiblingHelper = function(vObject, vParent, vCalc, vIgnoreClasses, vMode)
+{
+ if (!vIgnoreClasses) {
+ vIgnoreClasses = [];
+ }
+
+ var vChilds = vParent.getChildren();
+ var vPosition = qx.util.Validation.isInvalid(vMode) ? vChilds.indexOf(vObject) + vCalc : vMode == "first" ? 0 : vChilds.length-1;
+ var vInstance = vChilds[vPosition];
+
+ while(!vInstance.isEnabled() || qx.ui.core.Widget.getActiveSiblingHelperIgnore(vIgnoreClasses, vInstance))
+ {
+ vPosition += vCalc;
+ vInstance = vChilds[vPosition];
+
+ if (!vInstance) {
+ return null;
+ }
+ }
+
+ return vInstance;
+}
+
+
+
+
+
+
+
+/* ************************************************************************
+ Instance data, properties and methods
+************************************************************************ */
+
+/*
+---------------------------------------------------------------------------
+ UTILITIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ If the widget is visible and rendered on the screen.
+*/
+qx.Proto.isMaterialized = function() {
+ var el=this._element;
+ return (this._initialLayoutDone &&
+ this._isDisplayable &&
+ qx.dom.Style.getStyleProperty(el, "display") != "none" &&
+ qx.dom.Style.getStyleProperty(el, "visibility") != "hidden" &&
+ el.offsetWidth > 0 && el.offsetHeight > 0);
+}
+
+/*!
+ A single setup to the current preferred pixel values of the widget
+*/
+qx.Proto.pack = function()
+{
+ this.setWidth(this.getPreferredBoxWidth());
+ this.setHeight(this.getPreferredBoxHeight());
+}
+
+/*!
+ A bounded setup to the preferred width/height of the widget. Keeps in
+ sync if the content or requirements of the widget changes
+*/
+qx.Proto.auto = function()
+{
+ this.setWidth("auto");
+ this.setHeight("auto");
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CHILDREN HANDLING: ALL
+---------------------------------------------------------------------------
+*/
+
+/*!
+ Get an array of the current children
+*/
+qx.Proto.getChildren = qx.util.Return.returnNull;
+
+/*!
+ Get the number of children
+*/
+qx.Proto.getChildrenLength = qx.util.Return.returnZero;
+
+/*!
+ Get if the widget has any children
+*/
+qx.Proto.hasChildren = qx.util.Return.returnFalse;
+
+/*!
+ Get if the widget has no children
+*/
+qx.Proto.isEmpty = qx.util.Return.returnTrue;
+
+/*!
+ Return the position of the child inside
+*/
+qx.Proto.indexOf = qx.util.Return.returnNegativeIndex;
+
+/*!
+ Test if this widget contains the given widget
+*/
+qx.Proto.contains = qx.util.Return.returnFalse;
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CHILDREN HANDLING: VISIBLE ONES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ Get an array of the current visible children
+*/
+qx.Proto.getVisibleChildren = qx.util.Return.returnNull;
+
+/*!
+ Get the number of children
+*/
+qx.Proto.getVisibleChildrenLength = qx.util.Return.returnZero;
+
+/*!
+ If this widget has visible children
+*/
+qx.Proto.hasVisibleChildren = qx.util.Return.returnFalse;
+
+/*!
+ Check if there are any visible children inside
+*/
+qx.Proto.isVisibleEmpty = qx.util.Return.returnTrue;
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CORE MODIFIER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._hasParent = false;
+qx.Proto._isDisplayable = false;
+
+qx.Proto.isDisplayable = function() {
+ return this._isDisplayable;
+}
+
+qx.Proto._checkParent = function(propValue, propOldValue, propData)
+{
+ if (this.contains(propValue)) {
+ throw new Error("Could not insert myself into a child " + propValue + "!");
+ }
+
+ return propValue;
+}
+
+qx.Proto._modifyParent = function(propValue, propOldValue, propData)
+{
+ if (propOldValue)
+ {
+ var vOldIndex = propOldValue.getChildren().indexOf(this);
+
+ // Reset cached dimension and location values
+ this._computedWidthValue = this._computedMinWidthValue = this._computedMaxWidthValue = this._computedLeftValue = this._computedRightValue = null;
+ this._computedHeightValue = this._computedMinHeightValue = this._computedMaxHeightValue = this._computedTopValue = this._computedBottomValue = null;
+
+ this._cachedBoxWidth = this._cachedInnerWidth = this._cachedOuterWidth = null;
+ this._cachedBoxHeight = this._cachedInnerHeight = this._cachedOuterHeight = null;
+
+ // Finally remove from children array
+ qx.lang.Array.removeAt(propOldValue.getChildren(), vOldIndex);
+
+ // Invalidate visible children cache
+ propOldValue._invalidateVisibleChildren();
+
+ // Remove child from old parent's children queue
+ propOldValue._removeChildFromChildrenQueue(this);
+
+ // The layouter adds some layout jobs
+ propOldValue.getLayoutImpl().updateChildrenOnRemoveChild(this, vOldIndex);
+
+ // Inform job queue
+ propOldValue.addToJobQueue("removeChild");
+
+ // Invalidate inner preferred dimensions
+ propOldValue._invalidatePreferredInnerDimensions();
+
+ // Store old parent (needed later by _handleDisplayable)
+ this._oldParent = propOldValue;
+ }
+
+ if (propValue)
+ {
+ this._hasParent = true;
+
+ if (qx.util.Validation.isValidNumber(this._insertIndex))
+ {
+ qx.lang.Array.insertAt(propValue.getChildren(), this, this._insertIndex);
+ delete this._insertIndex;
+ }
+ else
+ {
+ propValue.getChildren().push(this);
+ }
+ }
+ else
+ {
+ this._hasParent = false;
+ }
+
+ return this._handleDisplayable("parent");
+}
+
+qx.Proto._modifyDisplay = function(propValue, propOldValue, propData) {
+ return this._handleDisplayable("display");
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPLAYBLE HANDLING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._handleDisplayable = function(vHint)
+{
+ // Detect changes. Return if there is no change.
+ // Also handle the case if the displayable keeps true and the parent
+ // was changed then we must not return here.
+ var vDisplayable = this._computeDisplayable();
+ if (this._isDisplayable == vDisplayable && !(vDisplayable && vHint == "parent")) {
+ return true;
+ }
+
+ this._isDisplayable = vDisplayable;
+
+ var vParent = this.getParent();
+
+ // Invalidate visible children
+ if (vParent)
+ {
+ vParent._invalidateVisibleChildren();
+ vParent._invalidatePreferredInnerDimensions();
+ }
+
+ // Remove old parent's elements from DOM and delete old parent
+ if (vHint && this._oldParent && this._oldParent._initialLayoutDone)
+ {
+ var vElement = this.getElement();
+ if(vElement)
+ {
+ if (this.getVisibility()) {
+ this._beforeDisappear();
+ }
+
+ this._beforeRemoveDom();
+
+ this._oldParent._getTargetNode().removeChild(vElement);
+
+ this._afterRemoveDom();
+
+ if (this.getVisibility()) {
+ this._afterDisappear();
+ }
+ }
+
+ delete this._oldParent;
+ }
+
+ // Handle 'show'
+ if (vDisplayable)
+ {
+ /* --------------------------------
+ Update current parent
+ -------------------------------- */
+
+ // The layouter added some layout jobs
+ if (vParent._initialLayoutDone)
+ {
+ vParent.getLayoutImpl().updateChildrenOnAddChild(this, vParent.getChildren().indexOf(this));
+
+ // Inform parents job queue
+ vParent.addToJobQueue("addChild");
+ }
+
+ // Add to parents children queue
+ // (indirectly with a new layout request)
+ this.addToLayoutChanges("initial");
+
+ // Add to custom queues
+ this.addToCustomQueues(vHint);
+
+ // Handle beforeAppear signals
+ if (this.getVisibility()) {
+ this._beforeAppear();
+ }
+
+
+
+ /* --------------------------------
+ Add to global Queues
+ -------------------------------- */
+
+ // Add element (and create if not ready)
+ if (!this._isCreated) {
+ qx.ui.core.Widget.addToGlobalElementQueue(this);
+ }
+
+ // Add to global queues
+ qx.ui.core.Widget.addToGlobalStateQueue(this);
+
+ if (!qx.lang.Object.isEmpty(this._jobQueue)) {
+ qx.ui.core.Widget.addToGlobalJobQueue(this);
+ }
+
+ if (!qx.lang.Object.isEmpty(this._childrenQueue)) {
+ qx.ui.core.Widget.addToGlobalLayoutQueue(this);
+ }
+ }
+
+ // Handle 'hide'
+ else
+ {
+ // Removing from global queues
+ qx.ui.core.Widget.removeFromGlobalElementQueue(this);
+ qx.ui.core.Widget.removeFromGlobalStateQueue(this);
+ qx.ui.core.Widget.removeFromGlobalJobQueue(this);
+ qx.ui.core.Widget.removeFromGlobalLayoutQueue(this);
+
+ // Add to top-level tree queue
+ this.removeFromCustomQueues(vHint);
+
+ // only remove when itself want to be removed
+ // through a property change - not a parent signal
+ if (vParent && vHint)
+ {
+ if (this.getVisibility()) {
+ this._beforeDisappear();
+ }
+
+ // The layouter added some layout jobs
+ if (vParent._initialLayoutDone && this._initialLayoutDone)
+ {
+ vParent.getLayoutImpl().updateChildrenOnRemoveChild(this, vParent.getChildren().indexOf(this));
+
+ // Inform parent's job queue
+ vParent.addToJobQueue("removeChild");
+
+ // Before Remove DOM Event
+ this._beforeRemoveDom();
+
+ // DOM action
+ vParent._getTargetNode().removeChild(this.getElement());
+
+ // After Remove DOM Event
+ this._afterRemoveDom();
+ }
+
+ // Remove from parents children queue
+ vParent._removeChildFromChildrenQueue(this);
+
+ if (this.getVisibility()) {
+ this._afterDisappear();
+ }
+ }
+ }
+
+ this._handleDisplayableCustom(vDisplayable, vParent, vHint);
+
+ return true;
+}
+
+qx.Proto.addToCustomQueues = qx.util.Return.returnTrue;
+qx.Proto.removeFromCustomQueues = qx.util.Return.returnTrue;
+
+qx.Proto._handleDisplayableCustom = qx.util.Return.returnTrue;
+
+qx.Proto._computeDisplayable = function() {
+ return this.getDisplay() && this._hasParent && this.getParent()._isDisplayable ? true : false;
+}
+
+qx.Proto._beforeAppear = function()
+{
+ // this.debug("_beforeAppear");
+ this.createDispatchEvent("beforeAppear");
+}
+
+qx.Proto._afterAppear = function()
+{
+ // this.debug("_afterAppear");
+ this._isSeeable = true;
+ this.createDispatchEvent("appear");
+}
+
+qx.Proto._beforeDisappear = function()
+{
+ // this.debug("_beforeDisappear");
+
+ // Remove any hover/pressed styles
+ this.removeState("over");
+
+ if (qx.OO.isAvailable("qx.ui.form.Button"))
+ {
+ this.removeState("pressed");
+ this.removeState("abandoned");
+ }
+
+ // this.debug("_beforeDisappear");
+ this.createDispatchEvent("beforeDisappear");
+}
+
+qx.Proto._afterDisappear = function()
+{
+ // this.debug("_afterDisappear");
+ this._isSeeable = false;
+ this.createDispatchEvent("disappear");
+}
+
+qx.Proto._isSeeable = false;
+
+/**
+ * If the widget is currently seeable which means that it:
+ *
+ * * has a also seeable parent
+ * * visibility is true
+ * * display is true
+ */
+qx.Proto.isSeeable = function() {
+ return this._isSeeable;
+}
+
+qx.Proto.isAppearRelevant = function() {
+ return this.getVisibility() && this._isDisplayable;
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DOM SIGNAL HANDLING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._beforeInsertDom = function()
+{
+ // this.debug("_beforeInsertDom");
+ this.createDispatchEvent("beforeInsertDom");
+}
+
+qx.Proto._afterInsertDom = function()
+{
+ // this.debug("_afterInsertDom");
+ this.createDispatchEvent("insertDom");
+}
+
+qx.Proto._beforeRemoveDom = function()
+{
+ // this.debug("_beforeRemoveDom");
+ this.createDispatchEvent("beforeRemoveDom");
+}
+
+qx.Proto._afterRemoveDom = function()
+{
+ // this.debug("_afterRemoveDom");
+ this.createDispatchEvent("removeDom");
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ VISIBILITY HANDLING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyVisibility = function(propValue, propOldValue, propData)
+{
+ if (propValue)
+ {
+ if (this._isDisplayable) {
+ this._beforeAppear();
+ }
+
+ this.removeStyleProperty("display");
+
+ if (this._isDisplayable) {
+ this._afterAppear();
+ }
+ }
+ else
+ {
+ if (this._isDisplayable) {
+ this._beforeDisappear();
+ }
+
+ this.setStyleProperty("display", "none");
+
+ if (this._isDisplayable) {
+ this._afterDisappear();
+ }
+ }
+
+ return true;
+}
+
+qx.Proto.show = function()
+{
+ this.setVisibility(true);
+ this.setDisplay(true);
+}
+
+qx.Proto.hide = function() {
+ this.setVisibility(false);
+}
+
+qx.Proto.connect = function() {
+ this.setDisplay(true);
+}
+
+qx.Proto.disconnect = function() {
+ this.setDisplay(false);
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ ENHANCED BORDER SUPPORT
+---------------------------------------------------------------------------
+*/
+
+if (qx.sys.Client.getInstance().isGecko())
+{
+ qx.Proto._createElementForEnhancedBorder = qx.util.Return.returnTrue;
+}
+else
+{
+ qx.Proto._createElementForEnhancedBorder = function()
+ {
+ // Enhanced Border Test (for IE and Opera)
+ if (qx.renderer.border.Border.enhancedCrossBrowserMode &&
+ this.getTagName() == "div" &&
+ !this._borderElement)
+ {
+ var el = this.getElement();
+ var cl = this._borderElement = document.createElement("div");
+
+ var es = el.style;
+ var cs = this._borderStyle = cl.style;
+
+ cs.width = cs.height = "100%";
+ cs.position = "absolute";
+
+ for (var i in this._styleProperties)
+ {
+ switch(i)
+ {
+ case "position":
+ case "zIndex":
+ case "filter":
+ case "display":
+ break;
+
+ default:
+ cs[i] = this._styleProperties[i];
+ es[i] = "";
+ }
+ }
+
+ // Move existing children
+ while(el.firstChild) {
+ cl.appendChild(el.firstChild);
+ }
+
+ el.appendChild(cl);
+ }
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DOM ELEMENT HANDLING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._isCreated = false;
+
+if (qx.sys.Client.getInstance().isGecko())
+{
+ qx.Proto._getTargetNode = function() {
+ return this._element;
+ }
+}
+else
+{
+ qx.Proto._getTargetNode = function() {
+ return this._borderElement || this._element;
+ }
+}
+
+qx.Proto.addToDocument = function() {
+ qx.ui.core.ClientDocument.getInstance().add(this);
+}
+
+/*!
+ Check if the widget is created (or the element is already available).
+*/
+qx.Proto.isCreated = function() {
+ return this._isCreated;
+}
+
+/*!
+ Create widget with empty element (of specified tagname).
+*/
+qx.Proto._createElementImpl = function() {
+ this.setElement(this.getTopLevelWidget().getDocumentElement().createElement(this.getTagName()));
+}
+
+qx.Proto._modifyElement = function(propValue, propOldValue, propData)
+{
+ this._isCreated = qx.util.Validation.isValidElement(propValue);
+
+ if (propOldValue)
+ {
+ // reset reference to widget instance
+ propOldValue.qx_Widget = null;
+
+ // remove events
+ this._removeInlineEvents(propOldValue);
+ }
+
+ if (propValue)
+ {
+ // add reference to widget instance
+ propValue.qx_Widget = this;
+
+ // link element and style reference
+ this._element = propValue;
+ this._style = propValue.style;
+
+ this._applyStyleProperties(propValue);
+ this._applyHtmlProperties(propValue);
+ this._applyHtmlAttributes(propValue);
+ this._applyElementData(propValue);
+
+ // attach inline events
+ this._addInlineEvents(propValue);
+
+ // send out create event
+ this.createDispatchEvent("create");
+ }
+ else
+ {
+ this._element = this._style = null;
+ }
+
+ return true;
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ JOBS QUEUE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.addToJobQueue = function(p)
+{
+ if (this._hasParent) {
+ qx.ui.core.Widget.addToGlobalJobQueue(this);
+ }
+
+ if (!this._jobQueue) {
+ this._jobQueue = {};
+ }
+
+ this._jobQueue[p] = true;
+ return true;
+}
+
+qx.Proto._flushJobQueue = function(q)
+{
+ /* --------------------------------------------------------------------------------
+ 1. Pre checks
+ -------------------------------------------------------------------------------- */
+
+ try
+ {
+ var vQueue = this._jobQueue;
+ var vParent = this.getParent();
+
+ if (!vParent || qx.lang.Object.isEmpty(vQueue)) {
+ return;
+ }
+
+ var vLayoutImpl = this instanceof qx.ui.core.Parent ? this.getLayoutImpl() : null;
+
+ if (vLayoutImpl) {
+ vLayoutImpl.updateSelfOnJobQueueFlush(vQueue);
+ }
+ }
+ catch(ex)
+ {
+ this.error("Flushing job queue (prechecks#1) failed", ex);
+ }
+
+
+
+
+
+ /* --------------------------------------------------------------------------------
+ 2. Recompute dimensions
+ -------------------------------------------------------------------------------- */
+
+ try
+ {
+ var vFlushParentJobQueue = false;
+ var vRecomputeOuterWidth = vQueue.marginLeft || vQueue.marginRight;
+ var vRecomputeOuterHeight = vQueue.marginTop || vQueue.marginBottom;
+ var vRecomputeInnerWidth = vQueue.frameWidth;
+ var vRecomputeInnerHeight = vQueue.frameHeight;
+ var vRecomputeParentPreferredInnerWidth = (vQueue.frameWidth || vQueue.preferredInnerWidth) && this._recomputePreferredBoxWidth();
+ var vRecomputeParentPreferredInnerHeight = (vQueue.frameHeight || vQueue.preferredInnerHeight) && this._recomputePreferredBoxHeight();
+
+ if (vRecomputeParentPreferredInnerWidth)
+ {
+ var vPref = this.getPreferredBoxWidth();
+
+ if (this._computedWidthTypeAuto)
+ {
+ this._computedWidthValue = vPref;
+ vQueue.width = true;
+ }
+
+ if (this._computedMinWidthTypeAuto)
+ {
+ this._computedMinWidthValue = vPref;
+ vQueue.minWidth = true;
+ }
+
+ if (this._computedMaxWidthTypeAuto)
+ {
+ this._computedMaxWidthValue = vPref;
+ vQueue.maxWidth = true;
+ }
+ }
+
+ if (vRecomputeParentPreferredInnerHeight)
+ {
+ var vPref = this.getPreferredBoxHeight();
+
+ if (this._computedHeightTypeAuto)
+ {
+ this._computedHeightValue = vPref;
+ vQueue.height = true;
+ }
+
+ if (this._computedMinHeightTypeAuto)
+ {
+ this._computedMinHeightValue = vPref;
+ vQueue.minHeight = true;
+ }
+
+ if (this._computedMaxHeightTypeAuto)
+ {
+ this._computedMaxHeightValue = vPref;
+ vQueue.maxHeight = true;
+ }
+ }
+
+ if ((vQueue.width || vQueue.minWidth || vQueue.maxWidth || vQueue.left || vQueue.right) && this._recomputeBoxWidth()) {
+ vRecomputeOuterWidth = vRecomputeInnerWidth = true;
+ }
+
+ if ((vQueue.height || vQueue.minHeight || vQueue.maxHeight || vQueue.top || vQueue.bottom) && this._recomputeBoxHeight()) {
+ vRecomputeOuterHeight = vRecomputeInnerHeight = true;
+ }
+ }
+ catch(ex)
+ {
+ this.error("Flushing job queue (recompute#2) failed", ex);
+ }
+
+
+
+
+
+ /* --------------------------------------------------------------------------------
+ 3. Signals to parent widgets
+ -------------------------------------------------------------------------------- */
+
+ try
+ {
+ if ((vRecomputeOuterWidth && this._recomputeOuterWidth()) ||
+ vRecomputeParentPreferredInnerWidth)
+ {
+ vParent._invalidatePreferredInnerWidth();
+ vParent.getLayoutImpl().updateSelfOnChildOuterWidthChange(this);
+
+ vFlushParentJobQueue = true;
+ }
+
+ if ((vRecomputeOuterHeight && this._recomputeOuterHeight()) ||
+ vRecomputeParentPreferredInnerHeight)
+ {
+ vParent._invalidatePreferredInnerHeight();
+ vParent.getLayoutImpl().updateSelfOnChildOuterHeightChange(this);
+
+ vFlushParentJobQueue = true;
+ }
+
+ if (vFlushParentJobQueue) {
+ vParent._flushJobQueue();
+ }
+ }
+ catch(ex)
+ {
+ this.error("Flushing job queue (parentsignals#3) failed", ex);
+ }
+
+
+
+
+
+ /* --------------------------------------------------------------------------------
+ 4. Add layout jobs
+ -------------------------------------------------------------------------------- */
+
+ try
+ {
+ // add to layout queue
+ vParent._addChildToChildrenQueue(this);
+
+ // convert jobs to layout jobs
+ for (var i in vQueue) {
+ this._layoutChanges[i] = true;
+ }
+ }
+ catch(ex)
+ {
+ this.error("Flushing job queue (addjobs#4) failed", ex);
+ }
+
+
+
+
+
+ /* --------------------------------------------------------------------------------
+ 5. Signals to children
+ -------------------------------------------------------------------------------- */
+
+ try
+ {
+ // inform children about padding change
+ if (this instanceof qx.ui.core.Parent &&
+ (vQueue.paddingLeft ||
+ vQueue.paddingRight ||
+ vQueue.paddingTop ||
+ vQueue.paddingBottom))
+ {
+ var ch=this.getChildren(), chl=ch.length;
+
+ if (vQueue.paddingLeft) {
+ for (var i=0; i<chl; i++) {
+ ch[i].addToLayoutChanges("parentPaddingLeft");
+ }
+ }
+
+ if (vQueue.paddingRight) {
+ for (var i=0; i<chl; i++) {
+ ch[i].addToLayoutChanges("parentPaddingRight");
+ }
+ }
+
+ if (vQueue.paddingTop) {
+ for (var i=0; i<chl; i++) {
+ ch[i].addToLayoutChanges("parentPaddingTop");
+ }
+ }
+
+ if (vQueue.paddingBottom) {
+ for (var i=0; i<chl; i++) {
+ ch[i].addToLayoutChanges("parentPaddingBottom");
+ }
+ }
+ }
+
+ if (vRecomputeInnerWidth) {
+ this._recomputeInnerWidth();
+ }
+
+ if (vRecomputeInnerHeight) {
+ this._recomputeInnerHeight();
+ }
+
+ if (this._initialLayoutDone)
+ {
+ if (vLayoutImpl) {
+ vLayoutImpl.updateChildrenOnJobQueueFlush(vQueue);
+ }
+ }
+ }
+ catch(ex)
+ {
+ this.error("Flushing job queue (childrensignals#5) failed", ex);
+ }
+
+
+
+ /* --------------------------------------------------------------------------------
+ 5. Cleanup
+ -------------------------------------------------------------------------------- */
+
+ delete this._jobQueue;
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ METHODS TO GIVE THE LAYOUTERS INFORMATION
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._isWidthEssential = qx.util.Return.returnTrue;
+qx.Proto._isHeightEssential = qx.util.Return.returnTrue;
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ APPLY LAYOUT STYLES
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget.initApplyMethods = function()
+{
+ var f = "_applyRuntime";
+ var r = "_resetRuntime";
+ var s = "this._style.";
+ var e = "=''";
+ var v = "=v+'px'";
+ var vpar = "v";
+
+ var props = ["left", "right", "top", "bottom", "width", "height",
+ "minWidth", "maxWidth", "minHeight", "maxHeight"];
+ var propsup = ["Left", "Right", "Top", "Bottom", "Width", "Height",
+ "MinWidth", "MaxWidth", "MinHeight", "MaxHeight"];
+
+ for (var i=0, fn=f+"Margin", rn=r+"Margin", sp=s+"margin"; i<4; i++)
+ {
+ qx.Proto[fn+propsup[i]] = new Function(vpar, sp + propsup[i] + v);
+ qx.Proto[rn+propsup[i]] = new Function(sp + propsup[i] + e);
+ }
+
+ var pad = "padding";
+ var upad = "Padding";
+
+ if (qx.sys.Client.getInstance().isGecko())
+ {
+ for (var i=0, fn=f+upad, rn=r+upad, sp=s+pad; i<4; i++)
+ {
+ qx.Proto[fn+propsup[i]] = new Function(vpar, sp + propsup[i] + v);
+ qx.Proto[rn+propsup[i]] = new Function(sp + propsup[i] + e);
+ }
+ }
+ else
+ {
+ // need to use setStyleProperty to keep compatibility with enhanced cross browser borders
+ var s1="this.setStyleProperty('padding";
+ var s2="', v+'px')";
+ var s3="this.removeStyleProperty('padding";
+ var s4="')";
+
+ for (var i=0, fn=f+upad, rn=r+upad, sp=s+pad; i<4; i++)
+ {
+ qx.Proto[fn+propsup[i]] = new Function(vpar, s1 + propsup[i] + s2);
+ qx.Proto[rn+propsup[i]] = new Function(s3 + propsup[i] + s4);
+ }
+ }
+
+ /*
+ Use optimized method for internet explorer
+ to omit string concat and directly setup
+ the new layout property.
+
+ We could not use this to reset the value however.
+ It seems that is just doesn't work this way. And the
+ left/top always get priority. Tried: "", null, "auto".
+ Nothing helps.
+
+ Now I've switched back to the conventional method
+ to reset the value. This seems to work again.
+ */
+ if (qx.sys.Client.getInstance().isMshtml())
+ {
+ for (var i=0, tpos="pos", vset="=v"; i<6; i++)
+ {
+ // to debug the values which will be applied use this instead of the
+ // first line:
+ // qx.Proto[f+propsup[i]] = new Function(vpar, "this.debug('v: ' + v); " + s + tpos + propsup[i] + vset);
+
+ qx.Proto[f+propsup[i]] = new Function(vpar, s + tpos + propsup[i] + vset);
+ qx.Proto[r+propsup[i]] = new Function(s + props[i] + e);
+ }
+ }
+ else
+ {
+ for (var i=0; i<10; i++)
+ {
+ // to debug the values which will be applied use this instead of the
+ // first line:
+ // qx.Proto[f+propsup[i]] = new Function(vpar, "this.debug('v: ' + v); " + s + props[i] + v);
+
+ qx.Proto[f+propsup[i]] = new Function(vpar, s + props[i] + v);
+ qx.Proto[r+propsup[i]] = new Function(s + props[i] + e);
+ }
+ }
+}
+
+qx.ui.core.Widget.initApplyMethods();
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DIMENSION CACHE
+---------------------------------------------------------------------------
+*/
+
+/*
+ Add basic setter/getters
+*/
+
+qx.OO.addCachedProperty({ name : "innerWidth", defaultValue : null });
+qx.OO.addCachedProperty({ name : "innerHeight", defaultValue : null });
+qx.OO.addCachedProperty({ name : "boxWidth", defaultValue : null });
+qx.OO.addCachedProperty({ name : "boxHeight", defaultValue : null });
+qx.OO.addCachedProperty({ name : "outerWidth", defaultValue : null });
+qx.OO.addCachedProperty({ name : "outerHeight", defaultValue : null });
+
+qx.Proto._computeBoxWidthFallback = function() {
+ return 0;
+}
+
+qx.Proto._computeBoxHeightFallback = function() {
+ return 0;
+}
+
+qx.Proto._computeBoxWidth = function() {
+ var vLayoutImpl = this.getParent().getLayoutImpl();
+ return Math.max(0,
+ qx.lang.Number.limit(vLayoutImpl.computeChildBoxWidth(this),
+ this.getMinWidthValue(),
+ this.getMaxWidthValue()));
+}
+
+qx.Proto._computeBoxHeight = function() {
+ var vLayoutImpl = this.getParent().getLayoutImpl();
+ return Math.max(0,
+ qx.lang.Number.limit(vLayoutImpl.computeChildBoxHeight(this),
+ this.getMinHeightValue(),
+ this.getMaxHeightValue()));
+}
+
+qx.Proto._computeOuterWidth = function() {
+ return Math.max(0,
+ (this.getMarginLeft() +
+ this.getBoxWidth() +
+ this.getMarginRight()));
+}
+
+qx.Proto._computeOuterHeight = function() {
+ return Math.max(0,
+ (this.getMarginTop() +
+ this.getBoxHeight() +
+ this.getMarginBottom()));
+}
+
+qx.Proto._computeInnerWidth = function() {
+ return Math.max(0, this.getBoxWidth() - this.getFrameWidth());
+}
+
+qx.Proto._computeInnerHeight = function() {
+ return Math.max(0, this.getBoxHeight() - this.getFrameHeight());
+}
+
+qx.Proto.getNeededWidth = function() {
+ var vLayoutImpl = this.getParent().getLayoutImpl();
+ return Math.max(0, vLayoutImpl.computeChildNeededWidth(this));
+}
+
+qx.Proto.getNeededHeight = function() {
+ var vLayoutImpl = this.getParent().getLayoutImpl();
+ return Math.max(0, vLayoutImpl.computeChildNeededHeight(this));
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ RECOMPUTE FLEX VALUES
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._recomputeFlexX = function()
+{
+ if (!this.getHasFlexX()) {
+ return false;
+ }
+
+ if (this._computedWidthTypeFlex)
+ {
+ this._computedWidthValue = null;
+ this.addToLayoutChanges("width");
+ }
+
+ return true;
+}
+
+qx.Proto._recomputeFlexY = function()
+{
+ if (!this.getHasFlexY()) {
+ return false;
+ }
+
+ if (this._computedHeightTypeFlex)
+ {
+ this._computedHeightValue = null;
+ this.addToLayoutChanges("height");
+ }
+
+ return true;
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ RECOMPUTE PERCENTS
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._recomputePercentX = function()
+{
+ if (!this.getHasPercentX()) {
+ return false;
+ }
+
+ if (this._computedWidthTypePercent)
+ {
+ this._computedWidthValue = null;
+ this.addToLayoutChanges("width");
+ }
+
+ if (this._computedMinWidthTypePercent)
+ {
+ this._computedMinWidthValue = null;
+ this.addToLayoutChanges("minWidth");
+ }
+
+ if (this._computedMaxWidthTypePercent)
+ {
+ this._computedMaxWidthValue = null;
+ this.addToLayoutChanges("maxWidth");
+ }
+
+ if (this._computedLeftTypePercent)
+ {
+ this._computedLeftValue = null;
+ this.addToLayoutChanges("left");
+ }
+
+ if (this._computedRightTypePercent)
+ {
+ this._computedRightValue = null;
+ this.addToLayoutChanges("right");
+ }
+
+ return true;
+}
+
+qx.Proto._recomputePercentY = function()
+{
+ if (!this.getHasPercentY()) {
+ return false;
+ }
+
+ if (this._computedHeightTypePercent)
+ {
+ this._computedHeightValue = null;
+ this.addToLayoutChanges("height");
+ }
+
+ if (this._computedMinHeightTypePercent)
+ {
+ this._computedMinHeightValue = null;
+ this.addToLayoutChanges("minHeight");
+ }
+
+ if (this._computedMaxHeightTypePercent)
+ {
+ this._computedMaxHeightValue = null;
+ this.addToLayoutChanges("maxHeight");
+ }
+
+ if (this._computedTopTypePercent)
+ {
+ this._computedTopValue = null;
+ this.addToLayoutChanges("top");
+ }
+
+ if (this._computedBottomTypePercent)
+ {
+ this._computedBottomValue = null;
+ this.addToLayoutChanges("bottom");
+ }
+
+ return true;
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ RECOMPUTE RANGES
+---------------------------------------------------------------------------
+*/
+
+if (qx.sys.Client.getInstance().isMshtml() || qx.sys.Client.getInstance().isOpera())
+{
+ qx.Proto._recomputeRangeX = function()
+ {
+ if (this._computedLeftTypeNull || this._computedRightTypeNull) {
+ return false;
+ }
+
+ this.addToLayoutChanges("width");
+ return true;
+ }
+
+ qx.Proto._recomputeRangeY = function()
+ {
+ if (this._computedTopTypeNull || this._computedBottomTypeNull) {
+ return false;
+ }
+
+ this.addToLayoutChanges("height");
+ return true;
+ }
+}
+else
+{
+ qx.Proto._recomputeRangeX = function() {
+ return !(this._computedLeftTypeNull || this._computedRightTypeNull);
+ }
+
+ qx.Proto._recomputeRangeY = function() {
+ return !(this._computedTopTypeNull || this._computedBottomTypeNull);
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ RECOMPUTE STRETCHING
+---------------------------------------------------------------------------
+*/
+
+if (qx.sys.Client.getInstance().isMshtml() || qx.sys.Client.getInstance().isOpera())
+{
+ qx.Proto._recomputeStretchingX = function()
+ {
+ if (this.getAllowStretchX() && this._computedWidthTypeNull)
+ {
+ this._computedWidthValue = null;
+ this.addToLayoutChanges("width");
+
+ return true;
+ }
+
+ return false;
+ }
+
+ qx.Proto._recomputeStretchingY = function()
+ {
+ if (this.getAllowStretchY() && this._computedHeightTypeNull)
+ {
+ this._computedHeightValue = null;
+ this.addToLayoutChanges("height");
+
+ return true;
+ }
+
+ return false;
+ }
+}
+else
+{
+ qx.Proto._recomputeStretchingX = function()
+ {
+ if (this.getAllowStretchX() && this._computedWidthTypeNull) {
+ return true;
+ }
+
+ return false;
+ }
+
+ qx.Proto._recomputeStretchingY = function()
+ {
+ if (this.getAllowStretchY() && this._computedHeightTypeNull) {
+ return true;
+ }
+
+ return false;
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ INTELLIGENT GETTERS FOR STANDALONE DIMENSIONS: HELPERS
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._computeValuePixel = function(v) {
+ return Math.round(v);
+}
+
+qx.Proto._computeValuePixelLimit = function(v) {
+ return Math.max(0, this._computeValuePixel(v));
+}
+
+qx.Proto._computeValuePercentX = function(v) {
+ return Math.round(this.getParent().getInnerWidthForChild(this) * v * 0.01);
+}
+
+qx.Proto._computeValuePercentXLimit = function(v) {
+ return Math.max(0, this._computeValuePercentX(v));
+}
+
+qx.Proto._computeValuePercentY = function(v) {
+ return Math.round(this.getParent().getInnerHeightForChild(this) * v * 0.01);
+}
+
+qx.Proto._computeValuePercentYLimit = function(v) {
+ return Math.max(0, this._computeValuePercentY(v));
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ INTELLIGENT GETTERS FOR STANDALONE DIMENSIONS: X-AXIS
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.getWidthValue = function()
+{
+ if (this._computedWidthValue != null) {
+ return this._computedWidthValue;
+ }
+
+ switch(this._computedWidthType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedWidthValue = this._computeValuePixelLimit(this._computedWidthParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedWidthValue = this._computeValuePercentXLimit(this._computedWidthParsed);
+
+ case qx.ui.core.Widget.TYPE_AUTO:
+ return this._computedWidthValue = this.getPreferredBoxWidth();
+
+ case qx.ui.core.Widget.TYPE_FLEX:
+ try{
+ this.getParent().getLayoutImpl().computeChildrenFlexWidth();
+ } catch (e){
+ if (this.getParent().getLayoutImpl()["computeChildrenFlexWidth"] == null){
+ throw new Error("Widget " + this + ": having flex size but parent layout does not support it");
+ } else {
+ throw e;
+ }
+ }
+ return this._computedWidthValue = this._computedWidthFlexValue;
+ }
+
+ return null;
+}
+
+qx.Proto.getMinWidthValue = function()
+{
+ if (this._computedMinWidthValue != null) {
+ return this._computedMinWidthValue;
+ }
+
+ switch(this._computedMinWidthType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedWidthValue = this._computeValuePixelLimit(this._computedMinWidthParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedWidthValue = this._computeValuePercentXLimit(this._computedMinWidthParsed);
+
+ case qx.ui.core.Widget.TYPE_AUTO:
+ return this._computedMinWidthValue = this.getPreferredBoxWidth();
+ }
+
+ return null;
+}
+
+qx.Proto.getMaxWidthValue = function()
+{
+ if (this._computedMaxWidthValue != null) {
+ return this._computedMaxWidthValue;
+ }
+
+ switch(this._computedMaxWidthType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedWidthValue = this._computeValuePixelLimit(this._computedMaxWidthParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedWidthValue = this._computeValuePercentXLimit(this._computedMaxWidthParsed);
+
+ case qx.ui.core.Widget.TYPE_AUTO:
+ return this._computedMaxWidthValue = this.getPreferredBoxWidth();
+ }
+
+ return null;
+}
+
+qx.Proto.getLeftValue = function()
+{
+ if (this._computedLeftValue != null) {
+ return this._computedLeftValue;
+ }
+
+ switch(this._computedLeftType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedLeftValue = this._computeValuePixel(this._computedLeftParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedLeftValue = this._computeValuePercentX(this._computedLeftParsed);
+ }
+
+ return null;
+}
+
+qx.Proto.getRightValue = function()
+{
+ if (this._computedRightValue != null) {
+ return this._computedRightValue;
+ }
+
+ switch(this._computedRightType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedRightValue = this._computeValuePixel(this._computedRightParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedRightValue = this._computeValuePercentX(this._computedRightParsed);
+ }
+
+ return null;
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ INTELLIGENT GETTERS FOR STANDALONE DIMENSIONS: Y-AXIS
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.getHeightValue = function()
+{
+ if (this._computedHeightValue != null) {
+ return this._computedHeightValue;
+ }
+
+ switch(this._computedHeightType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedHeightValue = this._computeValuePixelLimit(this._computedHeightParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedHeightValue = this._computeValuePercentYLimit(this._computedHeightParsed);
+
+ case qx.ui.core.Widget.TYPE_AUTO:
+ return this._computedHeightValue = this.getPreferredBoxHeight();
+
+ case qx.ui.core.Widget.TYPE_FLEX:
+ try{
+ this.getParent().getLayoutImpl().computeChildrenFlexHeight();
+ } catch (e){
+ if (this.getParent().getLayoutImpl()["computeChildrenFlexHeight"] == null){
+ throw new Error("Widget " + this + ": having flex size but parent layout does not support it");
+ } else {
+ throw e;
+ }
+ }
+ return this._computedHeightValue = this._computedHeightFlexValue;
+ }
+
+ return null;
+}
+
+qx.Proto.getMinHeightValue = function()
+{
+ if (this._computedMinHeightValue != null) {
+ return this._computedMinHeightValue;
+ }
+
+ switch(this._computedMinHeightType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedMinHeightValue = this._computeValuePixelLimit(this._computedMinHeightParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedMinHeightValue = this._computeValuePercentYLimit(this._computedMinHeightParsed);
+
+ case qx.ui.core.Widget.TYPE_AUTO:
+ return this._computedMinHeightValue = this.getPreferredBoxHeight();
+ }
+
+ return null;
+}
+
+qx.Proto.getMaxHeightValue = function()
+{
+ if (this._computedMaxHeightValue != null) {
+ return this._computedMaxHeightValue;
+ }
+
+ switch(this._computedMaxHeightType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedMaxHeightValue = this._computeValuePixelLimit(this._computedMaxHeightParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedMaxHeightValue = this._computeValuePercentYLimit(this._computedMaxHeightParsed);
+
+ case qx.ui.core.Widget.TYPE_AUTO:
+ return this._computedMaxHeightValue = this.getPreferredBoxHeight();
+ }
+
+ return null;
+}
+
+qx.Proto.getTopValue = function()
+{
+ if (this._computedTopValue != null) {
+ return this._computedTopValue;
+ }
+
+ switch(this._computedTopType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedTopValue = this._computeValuePixel(this._computedTopParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedTopValue = this._computeValuePercentY(this._computedTopParsed);
+ }
+
+ return null;
+}
+
+qx.Proto.getBottomValue = function()
+{
+ if (this._computedBottomValue != null) {
+ return this._computedBottomValue;
+ }
+
+ switch(this._computedBottomType)
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ return this._computedBottomValue = this._computeValuePixel(this._computedBottomParsed);
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ return this._computedBottomValue = this._computeValuePercentY(this._computedBottomParsed);
+ }
+
+ return null;
+}
+
+
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ FRAME DIMENSIONS
+---------------------------------------------------------------------------
+*/
+
+qx.OO.addCachedProperty({ name : "frameWidth", defaultValue : null, addToQueueRuntime : true });
+qx.OO.addCachedProperty({ name : "frameHeight", defaultValue : null, addToQueueRuntime : true });
+
+qx.Proto._computeFrameWidth = function()
+{
+ var fw = this._cachedBorderLeft + this.getPaddingLeft() + this.getPaddingRight() + this._cachedBorderRight;
+
+ switch(this.getOverflow())
+ {
+ case "scroll":
+ case "scrollY":
+ qx.ui.core.Widget.initOverflow();
+ fw += qx.ui.core.Widget.SCROLLBAR_SIZE;
+ break;
+
+ case "auto":
+ // This seems to be really hard to implement
+ // this.debug("Check Auto Scroll-X: " + this.getPreferredBoxHeight() + " :: " + this.getBoxHeight());
+ break;
+ }
+
+ return fw;
+}
+
+qx.Proto._computeFrameHeight = function()
+{
+ var fh = this._cachedBorderTop + this.getPaddingTop() + this.getPaddingBottom() + this._cachedBorderBottom;
+
+ switch(this.getOverflow())
+ {
+ case "scroll":
+ case "scrollX":
+ qx.ui.core.Widget.initOverflow();
+ fh += qx.ui.core.Widget.SCROLLBAR_SIZE;
+ break;
+
+ case "auto":
+ // This seems to be really hard to implement
+ // this.debug("Check Auto Scroll-Y: " + this.getPreferredBoxWidth() + " :: " + this.getBoxWidth());
+ break;
+ }
+
+ return fh;
+}
+
+qx.Proto._invalidateFrameDimensions = function()
+{
+ this._invalidateFrameWidth();
+ this._invalidateFrameHeight();
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ PREFERRED DIMENSIONS: INNER
+---------------------------------------------------------------------------
+*/
+
+qx.OO.addCachedProperty({ name : "preferredInnerWidth", defaultValue : null, addToQueueRuntime : true });
+qx.OO.addCachedProperty({ name : "preferredInnerHeight", defaultValue : null, addToQueueRuntime : true });
+
+qx.Proto._invalidatePreferredInnerDimensions = function()
+{
+ this._invalidatePreferredInnerWidth();
+ this._invalidatePreferredInnerHeight();
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ PREFERRED DIMENSIONS: BOX
+---------------------------------------------------------------------------
+*/
+
+qx.OO.addCachedProperty({ name : "preferredBoxWidth", defaultValue : null });
+qx.OO.addCachedProperty({ name : "preferredBoxHeight", defaultValue : null });
+
+qx.Proto._computePreferredBoxWidth = function()
+{
+ try {
+ return Math.max(0, this.getPreferredInnerWidth() + this.getFrameWidth());
+ } catch(ex) {
+ this.error("_computePreferredBoxWidth failed", ex);
+ }
+}
+
+qx.Proto._computePreferredBoxHeight = function()
+{
+ try {
+ return Math.max(0, this.getPreferredInnerHeight() + this.getFrameHeight());
+ } catch(ex) {
+ this.error("_computePreferredBoxHeight failed", ex);
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ LAYOUT QUEUE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._initialLayoutDone = false;
+
+qx.Proto.addToLayoutChanges = function(p)
+{
+ if (this._isDisplayable) {
+ this.getParent()._addChildToChildrenQueue(this);
+ }
+
+ return this._layoutChanges[p] = true;
+}
+
+qx.Proto.addToQueue = function(p) {
+ this._initialLayoutDone ? this.addToJobQueue(p) : this.addToLayoutChanges(p);
+}
+
+qx.Proto.addToQueueRuntime = function(p) {
+ return !this._initialLayoutDone || this.addToJobQueue(p);
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ BORDER/MARGIN/PADDING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._applyBorderX = function(vChild, vChanges, vStyle)
+{
+ var vBorder = vChild.getBorder();
+ vBorder ? vBorder._applyWidgetX(vChild) : qx.renderer.border.Border._resetBorderX(vChild);
+}
+
+qx.Proto._applyBorderY = function(vChild, vChanges, vStyle)
+{
+ var vBorder = vChild.getBorder();
+ vBorder ? vBorder._applyWidgetY(vChild) : qx.renderer.border.Border._resetBorderY(vChild);
+}
+
+qx.Proto._applyPaddingX = qx.util.Return.returnTrue;
+qx.Proto._applyPaddingY = qx.util.Return.returnTrue;
+
+
+
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ LAYOUT AUTO/PERCENT CACHE
+---------------------------------------------------------------------------
+*/
+
+qx.OO.addCachedProperty({ name : "hasPercentX", defaultValue : false });
+qx.OO.addCachedProperty({ name : "hasPercentY", defaultValue : false });
+qx.OO.addCachedProperty({ name : "hasAutoX", defaultValue : false });
+qx.OO.addCachedProperty({ name : "hasAutoY", defaultValue : false });
+qx.OO.addCachedProperty({ name : "hasFlexX", defaultValue : false });
+qx.OO.addCachedProperty({ name : "hasFlexY", defaultValue : false });
+
+qx.Proto._computeHasPercentX = function() {
+ return (this._computedLeftTypePercent ||
+ this._computedWidthTypePercent ||
+ this._computedMinWidthTypePercent ||
+ this._computedMaxWidthTypePercent ||
+ this._computedRightTypePercent);
+}
+
+qx.Proto._computeHasPercentY = function() {
+ return (this._computedTopTypePercent ||
+ this._computedHeightTypePercent ||
+ this._computedMinHeightTypePercent ||
+ this._computedMaxHeightTypePercent ||
+ this._computedBottomTypePercent);
+}
+
+qx.Proto._computeHasAutoX = function() {
+ return (this._computedWidthTypeAuto ||
+ this._computedMinWidthTypeAuto ||
+ this._computedMaxWidthTypeAuto);
+}
+
+qx.Proto._computeHasAutoY = function() {
+ return (this._computedHeightTypeAuto ||
+ this._computedMinHeightTypeAuto ||
+ this._computedMaxHeightTypeAuto);
+}
+
+qx.Proto._computeHasFlexX = function() {
+ return this._computedWidthTypeFlex;
+}
+
+qx.Proto._computeHasFlexY = function() {
+ return this._computedHeightTypeFlex;
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ LAYOUT TYPE INDENTIFY HELPER METHODS
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget.TYPE_NULL = 0;
+qx.ui.core.Widget.TYPE_PIXEL = 1;
+qx.ui.core.Widget.TYPE_PERCENT = 2;
+qx.ui.core.Widget.TYPE_AUTO = 3;
+qx.ui.core.Widget.TYPE_FLEX = 4;
+
+qx.Proto._evalUnitsPixelPercentAutoFlex = function(propValue)
+{
+ switch(propValue)
+ {
+ case "auto":
+ return qx.ui.core.Widget.TYPE_AUTO;
+
+ case Infinity:
+ case -Infinity:
+ return qx.ui.core.Widget.TYPE_NULL;
+ }
+
+ switch(typeof propValue)
+ {
+ case "number":
+ return isNaN(propValue) ? qx.ui.core.Widget.TYPE_NULL : qx.ui.core.Widget.TYPE_PIXEL;
+
+ case "string":
+ return propValue.indexOf("%") != -1 ? qx.ui.core.Widget.TYPE_PERCENT : propValue.indexOf("*") != -1 ? qx.ui.core.Widget.TYPE_FLEX : qx.ui.core.Widget.TYPE_NULL;
+ }
+
+ return qx.ui.core.Widget.TYPE_NULL;
+}
+
+qx.Proto._evalUnitsPixelPercentAuto = function(propValue)
+{
+ switch(propValue)
+ {
+ case "auto":
+ return qx.ui.core.Widget.TYPE_AUTO;
+
+ case Infinity:
+ case -Infinity:
+ return qx.ui.core.Widget.TYPE_NULL;
+ }
+
+ switch(typeof propValue)
+ {
+ case "number":
+ return isNaN(propValue) ? qx.ui.core.Widget.TYPE_NULL : qx.ui.core.Widget.TYPE_PIXEL;
+
+ case "string":
+ return propValue.indexOf("%") != -1 ? qx.ui.core.Widget.TYPE_PERCENT : qx.ui.core.Widget.TYPE_NULL;
+ }
+
+ return qx.ui.core.Widget.TYPE_NULL;
+}
+
+qx.Proto._evalUnitsPixelPercent = function(propValue)
+{
+ switch(propValue)
+ {
+ case Infinity:
+ case -Infinity:
+ return qx.ui.core.Widget.TYPE_NULL;
+ }
+
+ switch(typeof propValue)
+ {
+ case "number":
+ return isNaN(propValue) ? qx.ui.core.Widget.TYPE_NULL : qx.ui.core.Widget.TYPE_PIXEL;
+
+ case "string":
+ return propValue.indexOf("%") != -1 ? qx.ui.core.Widget.TYPE_PERCENT : qx.ui.core.Widget.TYPE_NULL;
+ }
+
+ return qx.ui.core.Widget.TYPE_NULL;
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ LAYOUT TYPE AND VALUE KEY PRE-CACHE
+---------------------------------------------------------------------------
+*/
+
+qx.ui.core.Widget.layoutPropertyTypes = {};
+
+qx.ui.core.Widget.initLayoutProperties = function()
+{
+ var a = [ "width", "height",
+ "minWidth", "maxWidth",
+ "minHeight", "maxHeight",
+ "left", "right", "top", "bottom" ];
+
+ for (var i=0, l=a.length, p, b, t; i<l; i++)
+ {
+ p = a[i];
+ b = "_computed" + qx.lang.String.toFirstUp(p);
+ t = b + "Type";
+
+ qx.ui.core.Widget.layoutPropertyTypes[p] =
+ {
+ dataType : t,
+ dataParsed : b + "Parsed",
+ dataValue : b + "Value",
+
+ typePixel : t + "Pixel",
+ typePercent : t + "Percent",
+ typeAuto : t + "Auto",
+ typeFlex : t + "Flex",
+ typeNull : t + "Null"
+ }
+ }
+}
+
+qx.ui.core.Widget.initLayoutProperties();
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ LAYOUT TYPE AND VALUE STORAGE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._unitDetectionPixelPercentAutoFlex = function(propData, propValue)
+{
+ var r = qx.ui.core.Widget.layoutPropertyTypes[propData.name];
+
+ var s = r.dataType;
+ var p = r.dataParsed;
+ var v = r.dataValue;
+
+ var s1 = r.typePixel;
+ var s2 = r.typePercent;
+ var s3 = r.typeAuto;
+ var s4 = r.typeFlex;
+ var s5 = r.typeNull;
+
+ var wasPercent = this[s2];
+ var wasAuto = this[s3];
+ var wasFlex = this[s4];
+
+ switch(this[s] = this._evalUnitsPixelPercentAutoFlex(propValue))
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ this[s1] = true;
+ this[s2] = this[s3] = this[s4] = this[s5] = false;
+ this[p] = this[v] = Math.round(propValue);
+ break;
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ this[s2] = true;
+ this[s1] = this[s3] = this[s4] = this[s5] = false;
+ this[p] = parseFloat(propValue);
+ this[v] = null;
+ break;
+
+ case qx.ui.core.Widget.TYPE_AUTO:
+ this[s3] = true;
+ this[s1] = this[s2] = this[s4] = this[s5] = false;
+ this[p] = this[v] = null;
+ break;
+
+ case qx.ui.core.Widget.TYPE_FLEX:
+ this[s4] = true;
+ this[s1] = this[s2] = this[s3] = this[s5] = false;
+ this[p] = parseFloat(propValue);
+ this[v] = null;
+ break;
+
+ default:
+ this[s5] = true;
+ this[s1] = this[s2] = this[s3] = this[s4] = false;
+ this[p] = this[v] = null;
+ break;
+ }
+
+ if (wasPercent != this[s2])
+ {
+ switch(propData.name)
+ {
+ case "minWidth":
+ case "maxWidth":
+ case "width":
+ case "left":
+ case "right":
+ this._invalidateHasPercentX();
+ break;
+
+ case "maxHeight":
+ case "minHeight":
+ case "height":
+ case "top":
+ case "bottom":
+ this._invalidateHasPercentY();
+ break;
+ }
+ }
+
+ // No ELSE because you can also switch from percent to auto
+ if (wasAuto != this[s3])
+ {
+ switch(propData.name)
+ {
+ case "minWidth":
+ case "maxWidth":
+ case "width":
+ this._invalidateHasAutoX();
+ break;
+
+ case "minHeight":
+ case "maxHeight":
+ case "height":
+ this._invalidateHasAutoY();
+ break;
+ }
+ }
+
+ // No ELSE because you can also switch from percent to auto
+ if (wasFlex != this[s4])
+ {
+ switch(propData.name)
+ {
+ case "width":
+ this._invalidateHasFlexX();
+ break;
+
+ case "height":
+ this._invalidateHasFlexY();
+ break;
+ }
+ }
+}
+
+qx.Proto._unitDetectionPixelPercentAuto = function(propData, propValue)
+{
+ var r = qx.ui.core.Widget.layoutPropertyTypes[propData.name];
+
+ var s = r.dataType;
+ var p = r.dataParsed;
+ var v = r.dataValue;
+
+ var s1 = r.typePixel;
+ var s2 = r.typePercent;
+ var s3 = r.typeAuto;
+ var s4 = r.typeNull;
+
+ var wasPercent = this[s2];
+ var wasAuto = this[s3];
+
+ switch(this[s] = this._evalUnitsPixelPercentAuto(propValue))
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ this[s1] = true;
+ this[s2] = this[s3] = this[s4] = false;
+ this[p] = this[v] = Math.round(propValue);
+ break;
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ this[s2] = true;
+ this[s1] = this[s3] = this[s4] = false;
+ this[p] = parseFloat(propValue);
+ this[v] = null;
+ break;
+
+ case qx.ui.core.Widget.TYPE_AUTO:
+ this[s3] = true;
+ this[s1] = this[s2] = this[s4] = false;
+ this[p] = this[v] = null;
+ break;
+
+ default:
+ this[s4] = true;
+ this[s1] = this[s2] = this[s3] = false;
+ this[p] = this[v] = null;
+ break;
+ }
+
+ if (wasPercent != this[s2])
+ {
+ switch(propData.name)
+ {
+ case "minWidth":
+ case "maxWidth":
+ case "width":
+ case "left":
+ case "right":
+ this._invalidateHasPercentX();
+ break;
+
+ case "minHeight":
+ case "maxHeight":
+ case "height":
+ case "top":
+ case "bottom":
+ this._invalidateHasPercentY();
+ break;
+ }
+ }
+
+ // No ELSE because you can also switch from percent to auto
+ if (wasAuto != this[s3])
+ {
+ switch(propData.name)
+ {
+ case "minWidth":
+ case "maxWidth":
+ case "width":
+ this._invalidateHasAutoX();
+ break;
+
+ case "minHeight":
+ case "maxHeight":
+ case "height":
+ this._invalidateHasAutoY();
+ break;
+ }
+ }
+}
+
+qx.Proto._unitDetectionPixelPercent = function(propData, propValue)
+{
+ var r = qx.ui.core.Widget.layoutPropertyTypes[propData.name];
+
+ var s = r.dataType;
+ var p = r.dataParsed;
+ var v = r.dataValue;
+
+ var s1 = r.typePixel;
+ var s2 = r.typePercent;
+ var s3 = r.typeNull;
+
+ var wasPercent = this[s2];
+
+ switch(this[s] = this._evalUnitsPixelPercent(propValue))
+ {
+ case qx.ui.core.Widget.TYPE_PIXEL:
+ this[s1] = true;
+ this[s2] = this[s3] = false;
+ this[p] = this[v] = Math.round(propValue);
+ break;
+
+ case qx.ui.core.Widget.TYPE_PERCENT:
+ this[s2] = true;
+ this[s1] = this[s3] = false;
+ this[p] = parseFloat(propValue);
+ this[v] = null;
+ break;
+
+ default:
+ this[s3] = true;
+ this[s1] = this[s2] = false;
+ this[p] = this[v] = null;
+ break;
+ }
+
+ if (wasPercent != this[s2])
+ {
+ switch(propData.name)
+ {
+ case "minWidth":
+ case "maxWidth":
+ case "width":
+ case "left":
+ case "right":
+ this._invalidateHasPercentX();
+ break;
+
+ case "minHeight":
+ case "maxHeight":
+ case "height":
+ case "top":
+ case "bottom":
+ this._invalidateHasPercentY();
+ break;
+ }
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ INLINE EVENTS
+---------------------------------------------------------------------------
+*/
+
+if (qx.sys.Client.getInstance().isMshtml())
+{
+ qx.ui.core.Widget.inlineEventMap =
+ {
+ input : "onpropertychange",
+ select : "onselect",
+ scroll : "onscroll",
+ focus : "onfocus",
+ blur : "onblur"
+ }
+
+ qx.Proto.enableInlineEvent = function(vEventName)
+ {
+ var vEventType = qx.ui.core.Widget.inlineEventMap[vEventName];
+
+ if (!this._inlineEvents)
+ {
+ this._inlineEvents = [vEventType];
+ }
+ else
+ {
+ this._inlineEvents.push(vEventType);
+ }
+
+ if (this._isCreated) {
+ this.getElement()[vEventType] = qx.ui.core.Widget.__oninlineevent;
+ }
+ }
+
+ qx.Proto.disableInlineEvent = function(vEventName)
+ {
+ var vEventType = qx.ui.core.Widget.inlineEventMap[vEventName];
+
+ if (this._inlineEvents) {
+ qx.lang.Array.remove(this._inlineEvents, vEventType);
+ }
+
+ if (this._isCreated) {
+ this.getElement()[vEventType] = null;
+ }
+ }
+
+ qx.Proto._addInlineEvents = function(vElement)
+ {
+ if (this._inlineEvents)
+ {
+ for (var i=0, a=this._inlineEvents, l=a.length; i<l; i++) {
+ vElement[a[i]] = qx.ui.core.Widget.__oninlineevent;
+ }
+ }
+ }
+
+ qx.Proto._removeInlineEvents = function(vElement)
+ {
+ if (this._inlineEvents)
+ {
+ for (var i=0, a=this._inlineEvents, l=a.length; i<l; i++) {
+ vElement[a[i]] = null;
+ }
+ }
+ }
+}
+else
+{
+ qx.Proto.enableInlineEvent = function(vEventName)
+ {
+ if (!this._inlineEvents)
+ {
+ this._inlineEvents = [vEventName];
+ }
+ else
+ {
+ this._inlineEvents.push(vEventName);
+ }
+
+ if (this._isCreated) {
+ this.getElement().addEventListener(vEventName, qx.ui.core.Widget.__oninlineevent, false);
+ }
+ }
+
+ qx.Proto.disableInlineEvent = function(vEventName)
+ {
+ if (this._inlineEvents) {
+ qx.lang.Array.remove(this._inlineEvents, vEventName);
+ }
+
+ if (this._isCreated) {
+ this.getElement().removeEventListener(vEventName, qx.ui.core.Widget.__oninlineevent, false);
+ }
+ }
+
+ qx.Proto._addInlineEvents = function(vElement)
+ {
+ if (this._inlineEvents)
+ {
+ for (var i=0, a=this._inlineEvents, l=a.length; i<l; i++) {
+ vElement.addEventListener(a[i], qx.ui.core.Widget.__oninlineevent, false);
+ }
+ }
+ }
+
+ qx.Proto._removeInlineEvents = function(vElement)
+ {
+ if (this._inlineEvents)
+ {
+ for (var i=0, a=this._inlineEvents, l=a.length; i<l; i++) {
+ vElement.removeEventListener(a[i], qx.ui.core.Widget.__oninlineevent, false);
+ }
+ }
+ }
+}
+
+qx.ui.core.Widget.__oninlineevent = function(e)
+{
+ if (!e) {
+ e = window.event;
+ }
+
+ if (this.qx_Widget) {
+ return this.qx_Widget._oninlineevent(e);
+ }
+}
+
+qx.Proto._oninlineevent = function(e)
+{
+ if (qx.ui.core.Widget._inFlushGlobalQueues) {
+ return;
+ }
+
+ // this.debug("Inlineevent: " + e.type);
+
+ switch(e.type)
+ {
+ case "propertychange":
+ this._oninlineproperty(e);
+ break;
+
+ case "input":
+ this._oninlineinput(e);
+ break;
+
+ default:
+ this.createDispatchEvent(e.type);
+ }
+}
+
+qx.Proto._oninlineinput = function(e)
+{
+ this.createDispatchDataEvent("input", this.getComputedValue());
+
+ // Block parents from this event
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ }
+
+ e.returnValue = -1;
+}
+
+qx.Proto._oninlineproperty = function(e)
+{
+ switch(e.propertyName)
+ {
+ case "value":
+ if (!this._inValueProperty) {
+ this._oninlineinput(e);
+ }
+
+ break;
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CHILDREN MANAGMENT
+---------------------------------------------------------------------------
+*/
+
+/*!
+ The widget which is at the top level,
+ which contains all others (normally a
+ instance of qx.ui.core.ClientDocument).
+*/
+qx.Proto.getTopLevelWidget = function() {
+ return this._hasParent ? this.getParent().getTopLevelWidget() : null;
+}
+
+/*!
+ Move myself to immediately before another child of the same parent.
+*/
+qx.Proto.moveSelfBefore = function(vBefore) {
+ this.getParent().addBefore(this, vBefore);
+}
+
+/*!
+ Move myself to immediately after another child of the same parent.
+*/
+qx.Proto.moveSelfAfter = function(vAfter) {
+ this.getParent().addAfter(this, vAfter);
+}
+
+/*!
+ Move myself to the head of the list: make me the first child.
+*/
+qx.Proto.moveSelfToBegin = function() {
+ this.getParent().addAtBegin(this);
+}
+
+/*!
+ Move myself to the end of the list: make me the last child.
+*/
+qx.Proto.moveSelfToEnd = function() {
+ this.getParent().addAtEnd(this);
+}
+
+/*!
+ Returns the previous sibling.
+*/
+qx.Proto.getPreviousSibling = function()
+{
+ var p = this.getParent();
+
+ if(p == null) {
+ return null;
+ }
+
+ var cs = p.getChildren();
+ return cs[cs.indexOf(this) - 1];
+}
+
+/*!
+ Returns the next sibling.
+*/
+qx.Proto.getNextSibling = function()
+{
+ var p = this.getParent();
+
+ if(p == null) {
+ return null;
+ }
+
+ var cs = p.getChildren();
+ return cs[cs.indexOf(this) + 1];
+}
+
+/*!
+ Returns the previous visible sibling.
+*/
+qx.Proto.getPreviousVisibleSibling = function()
+{
+ if(!this._hasParent) {
+ return null;
+ }
+
+ var vChildren = this.getParent().getVisibleChildren();
+ return vChildren[vChildren.indexOf(this) - 1];
+}
+
+/*!
+ Returns the next visible sibling.
+*/
+qx.Proto.getNextVisibleSibling = function()
+{
+ if(!this._hasParent) {
+ return null;
+ }
+
+ var vChildren = this.getParent().getVisibleChildren();
+ return vChildren[vChildren.indexOf(this) + 1];
+}
+
+qx.Proto.getPreviousActiveSibling = function(vIgnoreClasses)
+{
+ var vPrev = qx.ui.core.Widget.getActiveSiblingHelper(this, this.getParent(), -1, vIgnoreClasses, null);
+ return vPrev ? vPrev : this.getParent().getLastActiveChild();
+}
+
+qx.Proto.getNextActiveSibling = function(vIgnoreClasses)
+{
+ var vNext = qx.ui.core.Widget.getActiveSiblingHelper(this, this.getParent(), 1, vIgnoreClasses, null);
+ return vNext ? vNext : this.getParent().getFirstActiveChild();
+}
+
+qx.Proto.isFirstChild = function() {
+ return this._hasParent && this.getParent().getFirstChild() == this;
+}
+
+qx.Proto.isLastChild = function() {
+ return this._hasParent && this.getParent().getLastChild() == this;
+}
+
+qx.Proto.isFirstVisibleChild = function() {
+ return this._hasParent && this.getParent().getFirstVisibleChild() == this;
+}
+
+qx.Proto.isLastVisibleChild = function() {
+ return this._hasParent && this.getParent().getLastVisibleChild() == this;
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ ENABLED MODIFIER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyEnabled = function(propValue, propOldValue, propData)
+{
+ if (propValue)
+ {
+ this.removeState("disabled");
+ }
+ else
+ {
+ this.addState("disabled");
+
+ // Also reset some states to be sure a pressed/hovered button gets reset
+ this.removeState("over");
+
+ if (qx.OO.isAvailable("qx.ui.form.Button"))
+ {
+ this.removeState("abandoned");
+ this.removeState("pressed");
+ }
+ }
+
+ return true;
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ STATE HANDLING
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Returns whether a state is set.
+ *
+ * @param vState {string} the state to check.
+ * @return {boolean} whether the state is set.
+ */
+qx.Proto.hasState = function(vState) {
+ return this._states[vState] ? true : false;
+}
+
+/**
+ * Sets a state.
+ *
+ * @param state {string} the state to set.
+ */
+qx.Proto.addState = function(vState)
+{
+ if (! this._states[vState]) {
+ this._states[vState] = true;
+
+ if (this._hasParent) {
+ qx.ui.core.Widget.addToGlobalStateQueue(this);
+ }
+ }
+}
+
+/**
+ * Clears a state.
+ *
+ * @param vState {string} the state to clear.
+ */
+qx.Proto.removeState = function(vState)
+{
+ if (this._states[vState]) {
+ delete this._states[vState];
+
+ if (this._hasParent) {
+ qx.ui.core.Widget.addToGlobalStateQueue(this);
+ }
+ }
+}
+
+/**
+ * Sets or clears a state.
+ *
+ * @param state {string} the state to set or clear.
+ * @param enabled {boolean} whether the state should be set.
+ * If false it will be cleared.
+ */
+qx.Proto.setState = function(state, enabled) {
+ if (enabled) {
+ this.addState(state);
+ } else {
+ this.removeState(state);
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ APPEARANCE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._applyInitialAppearance = function()
+{
+ var vAppearance = this.getAppearance();
+
+ if (vAppearance)
+ {
+ try
+ {
+ var r = qx.manager.object.AppearanceManager.getInstance().getAppearanceTheme().initialFrom(vAppearance);
+ if (r) {
+ this.set(r);
+ }
+ }
+ catch(ex)
+ {
+ this.error("Could not apply initial appearance", ex);
+ }
+ }
+}
+
+qx.Proto._applyStateAppearance = function()
+{
+ // HACK: Is there a cleaner way to implement this?
+ // Maybe not use the appearance for this, but a simple property and event handler combination?
+ this._applyStateStyleFocus(this._states);
+
+ var vAppearance = this.getAppearance();
+
+ if (vAppearance)
+ {
+ try
+ {
+ var r = qx.manager.object.AppearanceManager.getInstance().getAppearanceTheme().stateFrom(vAppearance, this._states);
+ if (r) {
+ this.set(r);
+ }
+ }
+ catch(ex)
+ {
+ this.error("Could not apply state appearance", ex);
+ }
+ }
+}
+
+qx.Proto._resetAppearanceThemeWrapper = function(vNewAppearanceTheme, vOldAppearanceTheme)
+{
+ var vAppearance = this.getAppearance();
+
+ if (vAppearance)
+ {
+ var vOldAppearanceThemeObject = qx.manager.object.AppearanceManager.getInstance().getThemeById(vOldAppearanceTheme);
+ var vNewAppearanceThemeObject = qx.manager.object.AppearanceManager.getInstance().getThemeById(vNewAppearanceTheme);
+
+ var vOldAppearanceProperties = qx.lang.Object.mergeWith(vOldAppearanceThemeObject.initialFrom(vAppearance), vOldAppearanceThemeObject.stateFrom(vAppearance, this._states));
+ var vNewAppearanceProperties = qx.lang.Object.mergeWith(vNewAppearanceThemeObject.initialFrom(vAppearance), vNewAppearanceThemeObject.stateFrom(vAppearance, this._states));
+
+ for (var vProp in vOldAppearanceProperties)
+ {
+ if (!(vProp in vNewAppearanceProperties)) {
+ this[qx.OO.resetter[vProp]]();
+ }
+ }
+
+ this.set(vNewAppearanceProperties);
+ }
+}
+
+if (qx.sys.Client.getInstance().isMshtml())
+{
+ /*
+ Mshtml does not support outlines by css
+ */
+ qx.Proto._applyStateStyleFocus = function(vStates) {}
+}
+else if (qx.sys.Client.getInstance().isGecko())
+{
+ qx.Proto._applyStateStyleFocus = function(vStates)
+ {
+ if (vStates.focused)
+ {
+ if (!qx.event.handler.FocusHandler.mouseFocus && !this.getHideFocus())
+ {
+ this.setStyleProperty("MozOutline", "1px dotted invert");
+ }
+ }
+ else
+ {
+ this.removeStyleProperty("MozOutline");
+ }
+ }
+}
+else
+{
+ qx.Proto._applyStateStyleFocus = function(vStates)
+ {
+ if (vStates.focused)
+ {
+ if (!qx.event.handler.FocusHandler.mouseFocus && !this.getHideFocus())
+ {
+ this.setStyleProperty("outline", "1px dotted invert");
+ }
+ }
+ else
+ {
+ this.setStyleProperty("outline", "0px none");
+ }
+ }
+}
+
+qx.Proto.addToStateQueue = function() {
+ qx.ui.core.Widget.addToGlobalStateQueue(this);
+}
+
+qx.Proto.recursiveAddToStateQueue = function() {
+ this.addToStateQueue();
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ APPEARANCE MODIFIER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyAppearance = function(propValue, propOldValue, propData)
+{
+ var vAppearanceThemeObject = qx.manager.object.AppearanceManager.getInstance().getAppearanceTheme();
+
+ var vNewAppearanceProperties = vAppearanceThemeObject.initialFrom(propValue);
+
+ if (this.isCreated()) {
+ qx.lang.Object.mergeWith(vNewAppearanceProperties, vAppearanceThemeObject.stateFrom(propValue, this._states));
+ }
+
+ if (propOldValue)
+ {
+ var vOldAppearanceProperties = vAppearanceThemeObject.initialFrom(propOldValue);
+
+ if (this.isCreated()) {
+ qx.lang.Object.mergeWith(vOldAppearanceProperties, vAppearanceThemeObject.stateFrom(propOldValue, this._states));
+ }
+
+ for (var vProp in vOldAppearanceProperties)
+ {
+ if (!(vProp in vNewAppearanceProperties)) {
+ this[qx.OO.resetter[vProp]]();
+ }
+ }
+ }
+
+ this.set(vNewAppearanceProperties);
+
+ return true;
+}
+
+qx.Proto._recursiveAppearanceThemeUpdate = function(vNewAppearanceTheme, vOldAppearanceTheme)
+{
+ try
+ {
+ this._resetAppearanceThemeWrapper(vNewAppearanceTheme, vOldAppearanceTheme);
+ }
+ catch(ex)
+ {
+ this.error("Failed to update appearance theme", ex);
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ ELEMENT DATA
+---------------------------------------------------------------------------
+*/
+
+/*!
+ Placeholder method to add attributes and other content to element node
+*/
+qx.Proto._applyElementData = function(el) {}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ HTML PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.setHtmlProperty = function(propName, propValue)
+{
+ if (!this._htmlProperties) {
+ this._htmlProperties = {};
+ }
+
+ this._htmlProperties[propName] = propValue;
+
+ if (this._isCreated && this.getElement()[propName] != propValue) {
+ this.getElement()[propName] = propValue;
+ }
+
+ return true;
+}
+
+if (qx.sys.Client.getInstance().isMshtml())
+{
+ qx.Proto.removeHtmlProperty = function(propName)
+ {
+ if (!this._htmlProperties) {
+ return;
+ }
+
+ delete this._htmlProperties[propName];
+
+ if (this._isCreated) {
+ this.getElement().removeAttribute(propName);
+ }
+
+ return true;
+ }
+}
+else
+{
+ qx.Proto.removeHtmlProperty = function(propName)
+ {
+ if (!this._htmlProperties) {
+ return;
+ }
+
+ delete this._htmlProperties[propName];
+
+ if (this._isCreated)
+ {
+ this.getElement().removeAttribute(propName);
+ delete this.getElement()[propName];
+ }
+
+ return true;
+ }
+}
+
+qx.Proto.getHtmlProperty = function(propName)
+{
+ if (!this._htmlProperties) {
+ return "";
+ }
+
+ return this._htmlProperties[propName] || "";
+}
+
+qx.Proto._applyHtmlProperties = function(vElement)
+{
+ var vProperties = this._htmlProperties;
+
+ if (vProperties)
+ {
+ // this.debug("HTML-Properties: " + qx.lang.Object.getLength(vProperties));
+
+ var propName;
+
+ for (propName in vProperties) {
+ vElement[propName] = vProperties[propName];
+ }
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ HTML ATTRIBUTES
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.setHtmlAttribute = function(propName, propValue)
+{
+ if (!this._htmlAttributes) {
+ this._htmlAttributes = {};
+ }
+
+ this._htmlAttributes[propName] = propValue;
+
+ if (this._isCreated) {
+ this.getElement().setAttribute(propName, propValue);
+ }
+
+ return true;
+}
+
+qx.Proto.removeHtmlAttribute = function(propName)
+{
+ if (!this._htmlAttributes) {
+ return;
+ }
+
+ delete this._htmlAttributes[propName];
+
+ if (this._isCreated) {
+ this.getElement().removeAttribute(propName);
+ }
+
+ return true;
+}
+
+qx.Proto.getHtmlAttribute = function(propName)
+{
+ if (!this._htmlAttributes) {
+ return "";
+ }
+
+ return this._htmlAttributes[propName] || "";
+}
+
+qx.Proto._applyHtmlAttributes = function(vElement)
+{
+ var vAttributes = this._htmlAttributes;
+
+ if (vAttributes)
+ {
+ // this.debug("HTML-Attributes: " + qx.lang.Object.getLength(vAttributes));
+
+ var propName;
+
+ for (propName in vAttributes) {
+ vElement.setAttribute(propName, vAttributes[propName]);
+ }
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ STYLE PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.getStyleProperty = function(propName) {
+ return this._styleProperties[propName] || "";
+}
+
+qx.Proto.setStyleProperty = function(propName, propValue)
+{
+ this._styleProperties[propName] = propValue;
+
+ if (this._isCreated)
+ {
+ /*
+ The zIndex and filter properties should always be
+ applied on the "real" element node.
+ */
+ switch(propName)
+ {
+ case "zIndex":
+ case "filter":
+ case "display":
+ case "visibility":
+ var vElement = this.getElement();
+ break;
+
+ default:
+ var vElement = this._getTargetNode();
+ }
+
+ if (vElement) {
+ vElement.style[propName] = propValue;
+ }
+ }
+
+ return true;
+}
+
+qx.Proto.removeStyleProperty = function(propName)
+{
+ delete this._styleProperties[propName];
+
+ if (this._isCreated)
+ {
+ /*
+ The zIndex and filter properties should always be
+ applied on the "real" element node.
+ */
+ switch(propName)
+ {
+ case "zIndex":
+ case "filter":
+ case "display":
+ case "visibility":
+ var vElement = this.getElement();
+ break;
+
+ default:
+ var vElement = this._getTargetNode();
+ }
+
+ if (vElement) {
+ vElement.style[propName] = "";
+ }
+ }
+
+ return true;
+}
+
+qx.Proto._applyStyleProperties = function(vElement)
+{
+ var vProperties = this._styleProperties;
+ var propName;
+
+ var vBaseElement = vElement;
+ var vTargetElement = this._getTargetNode();
+
+ for (propName in vProperties)
+ {
+ /*
+ The zIndex and filter properties should always be
+ applied on the "real" element node.
+ */
+ switch(propName)
+ {
+ case "zIndex":
+ case "filter":
+ vElement = vBaseElement;
+ break;
+
+ default:
+ vElement = vTargetElement;
+ }
+
+ vElement.style[propName] = vProperties[propName];
+ }
+}
+
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ FOCUS HANDLING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.isFocusable = function() {
+ return this.isEnabled() && this.isSeeable() && this.getTabIndex() >= 0;
+}
+
+qx.Proto.isFocusRoot = function() {
+ return false;
+}
+
+qx.Proto.getFocusRoot = function()
+{
+ if(this._hasParent) {
+ return this.getParent().getFocusRoot();
+ }
+
+ return null;
+}
+
+qx.Proto.getActiveChild = function()
+{
+ var vRoot = this.getFocusRoot();
+ if (vRoot) {
+ return vRoot.getActiveChild();
+ }
+
+ return null;
+}
+
+qx.Proto._ontabfocus = qx.util.Return.returnTrue;
+
+qx.Proto._modifyFocused = function(propValue, propOldValue, propData)
+{
+ if (!this.isCreated()) {
+ return true;
+ }
+
+ var vFocusRoot = this.getFocusRoot();
+
+ // this.debug("Focused: " + propValue);
+
+ if (vFocusRoot)
+ {
+ // may be undefined if this widget has been removed
+ if (propValue)
+ {
+ vFocusRoot.setFocusedChild(this);
+ this._visualizeFocus();
+ }
+ else
+ {
+ if (vFocusRoot.getFocusedChild() == this) {
+ vFocusRoot.setFocusedChild(null);
+ }
+
+ this._visualizeBlur();
+ }
+ }
+
+ return true;
+}
+
+qx.Proto._visualizeBlur = function()
+{
+ // Force blur, even if mouseFocus is not active because we
+ // need to be sure that the previous focus rect gets removed.
+ // But this only needs to be done, if there is no new focused element.
+ if (this.getEnableElementFocus() && (!this.getFocusRoot().getFocusedChild() || (this.getFocusRoot().getFocusedChild() && this.getFocusRoot().getFocusedChild().getEnableElementFocus())))
+ {
+ try {
+ this.getElement().blur();
+ } catch(ex) {};
+ }
+
+ this.removeState("focused");
+ return true;
+}
+
+qx.Proto._visualizeFocus = function()
+{
+ //this.info("_visualizeFocus: " + qx.event.handler.FocusHandler.mouseFocus);
+ if (!qx.event.handler.FocusHandler.mouseFocus && this.getEnableElementFocus())
+ {
+ try {
+ this.getElement().focus();
+ } catch(ex) {};
+ }
+
+ this.addState("focused");
+ return true;
+}
+
+qx.Proto.focus = function()
+{
+ delete qx.event.handler.FocusHandler.mouseFocus;
+ this.setFocused(true);
+}
+
+qx.Proto.blur = function()
+{
+ delete qx.event.handler.FocusHandler.mouseFocus;
+ this.setFocused(false);
+}
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CAPTURE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyCapture = function(propValue, propOldValue, propData)
+{
+ var vMgr = qx.event.handler.EventHandler.getInstance();
+
+ if (propOldValue)
+ {
+ vMgr.setCaptureWidget(null);
+ }
+ else if (propValue)
+ {
+ vMgr.setCaptureWidget(this);
+ }
+
+ return true;
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ ZINDEX
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyZIndex = function(propValue, propOldValue, propData) {
+ return this.setStyleProperty(propData.name, propValue);
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ TAB INDEX
+---------------------------------------------------------------------------
+*/
+
+if (qx.sys.Client.getInstance().isMshtml())
+{
+ qx.Proto._modifyTabIndex = function(propValue, propOldValue, propData)
+ {
+ if (propValue < 0 || !this.getEnabled()) {
+ this.setHtmlProperty("unselectable",
+ "on");
+ } else {
+ this.removeHtmlProperty("unselectable");
+ }
+
+ this.setHtmlProperty("tabIndex",
+ propValue < 0 ? -1 : 1);
+
+ return true;
+ }
+}
+else if (qx.sys.Client.getInstance().isGecko())
+{
+ qx.Proto._modifyTabIndex = function(propValue, propOldValue, propData)
+ {
+ this.setStyleProperty("MozUserFocus",
+ (propValue < 0
+ ? "ignore"
+ : "normal"));
+
+ // be forward compatible (CSS 3 Draft)
+ this.setStyleProperty("userFocus",
+ (propValue < 0
+ ? "ignore"
+ : "normal"));
+
+ return true;
+ }
+}
+else
+{
+ qx.Proto._modifyTabIndex = function(propValue, propOldValue, propData)
+ {
+ // CSS 3 Draft
+ this.setStyleProperty("userFocus",
+ (propValue < 0
+ ? "ignore"
+ : "normal"));
+
+ // IE Backward Compatible
+ if (propValue < 0 || !this.getEnabled()) {
+ this.setHtmlProperty("unselectable",
+ "on");
+ } else {
+ this.removeHtmlProperty("unselectable");
+ }
+
+ this.setHtmlProperty("tabIndex",
+ propValue < 0 ? -1 : 1);
+
+ return true;
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CSS CLASS NAME
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.setCssClassName = function(propValue) {
+ this.setHtmlProperty("className", propValue);
+}
+
+qx.Proto.getCssClassName = function() {
+ return this.getHtmlProperty("className");
+}
+
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ WIDGET FROM POINT
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.getWidgetFromPoint = function(x, y)
+{
+ var ret = this.getWidgetFromPointHelper(x, y);
+ return ret && ret != this ? ret : null;
+}
+
+qx.Proto.getWidgetFromPointHelper = function(x, y) {
+ return this;
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CAN SELECT
+---------------------------------------------------------------------------
+*/
+
+if(qx.sys.Client.getInstance().isMshtml())
+{
+ qx.Proto._modifySelectable = function(propValue, propOldValue, propData)
+ {
+ if (propValue)
+ {
+ return this.removeHtmlProperty("unselectable");
+ }
+ else
+ {
+ return this.setHtmlProperty("unselectable", "on");
+ }
+ }
+}
+else if(qx.sys.Client.getInstance().isGecko())
+{
+ qx.Proto._modifySelectable = function(propValue, propOldValue, propData)
+ {
+ if (propValue)
+ {
+ this.removeStyleProperty("MozUserSelect");
+ }
+ else
+ {
+ this.setStyleProperty("MozUserSelect", "none");
+ }
+
+ return true;
+ };
+}
+else if (qx.sys.Client.getInstance().isOpera())
+{
+ // No known method available for this client
+ qx.Proto._modifySelectable = function(propValue, propOldValue, propData) {
+ return true;
+ }
+}
+else if (qx.sys.Client.getInstance().isKhtml() || qx.sys.Client.getInstance().isWebkit())
+{
+ qx.Proto._modifySelectable = function(propValue, propOldValue, propData)
+ {
+ // Be forward compatible and use both userSelect and KhtmlUserSelect
+ if (propValue)
+ {
+ this.removeStyleProperty("KhtmlUserSelect");
+ }
+ else
+ {
+ this.setStyleProperty("KhtmlUserSelect", "none");
+ }
+
+ return true;
+ };
+}
+else
+{
+ qx.Proto._modifySelectable = function(propValue, propOldValue, propData)
+ {
+ if (propValue)
+ {
+ return this.removeStyleProperty("userSelect");
+ }
+ else
+ {
+ this.setStyleProperty("userSelect", "none");
+ }
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ OPACITY
+---------------------------------------------------------------------------
+*/
+
+/*!
+Sets the opacity for the widget. Any child widget inside the widget will also
+become (semi-)transparent. The value should be a number between 0 and 1
+inclusive, where 1 means totally opaque and 0 invisible.
+*/
+if(qx.sys.Client.getInstance().isMshtml())
+{
+ qx.Proto._modifyOpacity = function(propValue, propOldValue, propData)
+ {
+ if(propValue == null || propValue >= 1 || propValue < 0)
+ {
+ this.removeStyleProperty("filter");
+ }
+ else if (qx.util.Validation.isValidNumber(propValue))
+ {
+ this.setStyleProperty("filter",
+ ("Alpha(Opacity=" +
+ Math.round(propValue * 100) +
+ ")"));
+ }
+ else
+ {
+ throw new Error("Unsupported opacity value: " + propValue);
+ }
+
+ return true;
+ }
+}
+else
+{
+ qx.Proto._modifyOpacity = function(propValue, propOldValue, propData)
+ {
+ if(propValue == null || propValue > 1)
+ {
+ if (qx.sys.Client.getInstance().isGecko())
+ {
+ this.removeStyleProperty("MozOpacity");
+ }
+ else if (qx.sys.Client.getInstance().isKhtml())
+ {
+ this.removeStyleProperty("KhtmlOpacity");
+ }
+
+ this.removeStyleProperty("opacity");
+ }
+ else if (qx.util.Validation.isValidNumber(propValue))
+ {
+ propValue = qx.lang.Number.limit(propValue, 0, 1);
+
+ // should we omit gecko's flickering here
+ // and limit the max value to 0.99?
+
+ if (qx.sys.Client.getInstance().isGecko())
+ {
+ this.setStyleProperty("MozOpacity", propValue);
+ }
+ else if (qx.sys.Client.getInstance().isKhtml())
+ {
+ this.setStyleProperty("KhtmlOpacity", propValue);
+ }
+
+ this.setStyleProperty("opacity", propValue);
+ }
+
+ return true;
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CURSOR
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyCursor = function(propValue, propOldValue, propData)
+{
+ if (propValue)
+ {
+ if (propValue == "pointer" &&
+ qx.sys.Client.getInstance().isMshtml()) {
+ this.setStyleProperty("cursor",
+ "hand");
+ } else {
+ this.setStyleProperty("cursor",
+ propValue);
+ }
+ }
+ else
+ {
+ this.removeStyleProperty("cursor");
+ }
+
+ return true;
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ BACKGROUND IMAGE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyBackgroundImage = function(propValue, propOldValue, propData)
+{
+ return qx.util.Validation.isValidString(propValue) ?
+ this.setStyleProperty("backgroundImage",
+ "url(" +
+ qx.manager.object.AliasManager.getInstance().resolvePath(propValue) +
+ ")") :
+ this.removeStyleProperty("backgroundImage");
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CLIPPING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyClip = function(propValue, propOldValue, propData) {
+ return this._compileClipString();
+}
+
+qx.Proto._compileClipString = function()
+{
+ var vLeft = this.getClipLeft();
+ var vTop = this.getClipTop();
+ var vWidth = this.getClipWidth();
+ var vHeight = this.getClipHeight();
+
+ var vRight, vBottom;
+
+ if(vLeft == null)
+ {
+ vRight = (vWidth == null
+ ? "auto"
+ : vWidth + "px");
+ vLeft = "auto";
+ }
+ else
+ {
+ vRight = (vWidth == null
+ ? "auto"
+ : vLeft + vWidth + "px");
+ vLeft = vLeft + "px";
+ }
+
+ if(vTop == null)
+ {
+ vBottom = (vHeight == null
+ ? "auto"
+ : vHeight + "px");
+ vTop = "auto";
+ }
+ else
+ {
+ vBottom = (vHeight == null
+ ? "auto"
+ : vTop + vHeight + "px");
+ vTop = vTop + "px";
+ }
+
+ return this.setStyleProperty("clip",
+ ("rect(" +
+ vTop +
+ "," +
+ vRight +
+ "," +
+ vBottom +
+ "," +
+ vLeft +
+ ")"));
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ OVERFLOW
+---------------------------------------------------------------------------
+*/
+
+/*
+ This will measure the typical native scrollbar size in the environment
+*/
+qx.ui.core.Widget.initOverflow = function()
+{
+ if (qx.ui.core.Widget.initOverflowDone) {
+ return;
+ }
+
+ var t = document.createElement("div");
+ var s = t.style;
+
+ s.height = s.width = "100px";
+ s.overflow = "scroll";
+
+ document.body.appendChild(t);
+
+ var c = qx.dom.Dimension.getScrollBarSizeRight(t);
+ if (c) {
+ qx.ui.core.Widget.SCROLLBAR_SIZE = c;
+ }
+
+ document.body.removeChild(t);
+
+ qx.ui.core.Widget.initOverflowDone = true;
+}
+
+if (qx.sys.Client.getInstance().isGecko())
+{
+ qx.Proto._modifyOverflow = function(propValue, propOldValue, propData)
+ {
+ var pv = propValue;
+ var pn = propData.name;
+
+ switch(pv)
+ {
+ case "hidden":
+ pv = "-moz-scrollbars-none";
+ break;
+
+ case "scrollX":
+ pv = "-moz-scrollbars-horizontal";
+ break;
+
+ case "scrollY":
+ pv = "-moz-scrollbars-vertical";
+ break;
+ }
+
+ return this._applyOverflow(pn, pv, propValue, propOldValue);
+ }
+}
+
+// Mshtml conforms here to CSS3 Spec. Eventually there will be multiple
+// browsers which support these new overflowX overflowY properties.
+else if (qx.sys.Client.getInstance().isMshtml())
+{
+ qx.Proto._modifyOverflow = function(propValue, propOldValue, propData)
+ {
+ var pv = propValue;
+ var pn = propData.name;
+
+ switch(pv)
+ {
+ case "scrollX":
+ pn = "overflowX";
+ pv = "scroll";
+ break;
+
+ case "scrollY":
+ pn = "overflowY";
+ pv = "scroll";
+ break;
+ }
+
+ // Clear up concurrenting rules
+ var a = [ "overflow",
+ "overflowX",
+ "overflowY" ];
+ for (var i=0; i<a.length; i++)
+ {
+ if (a[i]!=pn) {
+ this.removeStyleProperty(a[i]);
+ }
+ }
+
+ return this._applyOverflow(pn, pv, propValue, propOldValue);
+ }
+}
+
+// Opera/Khtml Mode...
+// hopefully somewhat of this is supported in the near future.
+
+// overflow-x and overflow-y are also not supported by Opera 9.0 Beta1
+// and also not if we switch to IE emulation mode
+else
+{
+ qx.Proto._modifyOverflow = function(propValue, propOldValue, propData)
+ {
+ var pv = propValue;
+ var pn = propData.name;
+
+ switch(pv)
+ {
+ case "scrollX":
+ case "scrollY":
+ pv = "scroll";
+ break;
+ }
+
+ return this._applyOverflow(pn, pv, propValue, propOldValue);
+ }
+}
+
+qx.Proto._applyOverflow = function(pn, pv, propValue, propOldValue)
+{
+ // Apply Style
+ this.setStyleProperty(pn, pv);
+
+ // Invalidate Frame
+ this._invalidateFrameWidth();
+ this._invalidateFrameHeight();
+
+ return true;
+}
+
+qx.Proto.getOverflowX = function()
+{
+ var vOverflow = this.getOverflow();
+ return vOverflow == "scrollY" ? "hidden" : vOverflow;
+}
+
+qx.Proto.getOverflowY = function()
+{
+ var vOverflow = this.getOverflow();
+ return vOverflow == "scrollX" ? "hidden" : vOverflow;
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ HIDE FOCUS
+---------------------------------------------------------------------------
+*/
+
+if (qx.sys.Client.getInstance().isMshtml())
+{
+ qx.Proto._modifyHideFocus = function(propValue, propOldValue, propData)
+ {
+ this.setHtmlProperty(propData.name, propValue);
+ return true;
+ }
+}
+
+// Need no implementation for others then mshtml, because
+// all these browsers support css outlines and do not
+// have an attribute "hideFocus" as IE.
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ COLORS
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyBackgroundColor = function(propValue, propOldValue, propData)
+{
+ if (propOldValue) {
+ propOldValue.remove(this);
+ }
+
+ if (propValue)
+ {
+ this._applyBackgroundColor(propValue.getStyle());
+ propValue.add(this);
+ }
+ else
+ {
+ this._resetBackgroundColor();
+ }
+
+ return true;
+}
+
+qx.Proto._modifyColor = function(propValue, propOldValue, propData)
+{
+ if (propOldValue) {
+ propOldValue.remove(this);
+ }
+
+ if (propValue)
+ {
+ this._applyColor(propValue.getStyle());
+ propValue.add(this);
+ }
+ else
+ {
+ this._resetColor();
+ }
+
+ return true;
+}
+
+qx.Proto._updateColors = function(vColor, vNewValue)
+{
+ if (this.getColor() == vColor) {
+ this._applyColor(vNewValue);
+ }
+
+ if (this.getBackgroundColor() == vColor) {
+ this._applyBackgroundColor(vNewValue);
+ }
+}
+
+qx.Proto._applyColor = function(vNewValue) {
+ this.setStyleProperty("color", vNewValue);
+}
+
+qx.Proto._applyBackgroundColor = function(vNewValue) {
+ this.setStyleProperty("backgroundColor", vNewValue);
+}
+
+qx.Proto._resetColor = function(vNewValue) {
+ this.removeStyleProperty("color");
+}
+
+qx.Proto._resetBackgroundColor = function() {
+ this.removeStyleProperty("backgroundColor");
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ BORDER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._cachedBorderTop = 0;
+qx.Proto._cachedBorderRight = 0;
+qx.Proto._cachedBorderBottom = 0;
+qx.Proto._cachedBorderLeft = 0;
+
+qx.Proto._modifyBorder = function(propValue, propOldValue, propData)
+{
+ var vOldTop = this._cachedBorderTop;
+ var vOldRight = this._cachedBorderRight;
+ var vOldBottom = this._cachedBorderBottom;
+ var vOldLeft = this._cachedBorderLeft;
+
+ if (propOldValue) {
+ propOldValue.removeListenerWidget(this);
+ }
+
+ if (propValue)
+ {
+ propValue.addListenerWidget(this);
+
+ this._cachedBorderTop = propValue.getTopWidth();
+ this._cachedBorderRight = propValue.getRightWidth();
+ this._cachedBorderBottom = propValue.getBottomWidth();
+ this._cachedBorderLeft = propValue.getLeftWidth();
+ }
+ else
+ {
+ this._cachedBorderTop = this._cachedBorderRight = this._cachedBorderBottom = this._cachedBorderLeft = 0;
+ }
+
+
+
+ // ----------------
+ // X-AXIS
+ // ----------------
+ if ((vOldLeft + vOldRight) != (this._cachedBorderLeft + this._cachedBorderRight)) {
+ this._invalidateFrameWidth();
+ }
+
+ this.addToQueue("borderX");
+
+
+
+ // ----------------
+ // Y-AXIS
+ // ----------------
+ if ((vOldTop + vOldBottom) != (this._cachedBorderTop + this._cachedBorderBottom)) {
+ this._invalidateFrameHeight();
+ }
+
+ this.addToQueue("borderY");
+
+
+
+
+
+ return true;
+}
+
+qx.Proto.getCachedBorderTop = function() {
+ return this._cachedBorderTop;
+}
+
+qx.Proto.getCachedBorderRight = function() {
+ return this._cachedBorderRight;
+}
+
+qx.Proto.getCachedBorderBottom = function() {
+ return this._cachedBorderBottom;
+}
+
+qx.Proto.getCachedBorderLeft = function() {
+ return this._cachedBorderLeft;
+}
+
+qx.Proto._updateBorder = function(vEdge)
+{
+ // Small hack, remove later: TODO
+ // ?? Anybody have an idea about this TODO?
+ var vBorder = this.getBorder();
+ var vEdgeUp = qx.lang.String.toFirstUp(vEdge);
+
+ var vNewValue = vBorder["get" + vEdgeUp + "Width"]();
+ var vCacheName = "_cachedBorder" + vEdgeUp;
+ var vWidthChanged = this[vCacheName] != vNewValue;
+
+ this[vCacheName] = vNewValue;
+
+ switch(vEdge)
+ {
+ case "left":
+ case "right":
+ if (vWidthChanged) {
+ this.addToJobQueue("borderWidthX");
+ }
+
+ this.addToJobQueue("borderX");
+ break;
+
+ case "top":
+ case "bottom":
+ if (vWidthChanged) {
+ this.addToJobQueue("borderWidthY");
+ }
+
+ this.addToJobQueue("borderY");
+ break;
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ PADDING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyPaddingX = function(propValue, propOldValue, propData)
+{
+ this._invalidateFrameWidth();
+ return true;
+}
+
+qx.Proto._modifyPaddingY = function(propValue, propOldValue, propData)
+{
+ this._invalidateFrameHeight();
+ return true;
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CLONE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._clonePropertyIgnoreList = "parent,element,visible";
+
+
+/*!
+Returns a cloned copy of the current instance of qx.ui.core.Widget.
+
+#param cloneRecursive[Boolean]: Should the widget cloned recursive (including all childs)?
+#param customPropertyList[Array]: Optional (reduced) list of properties to copy through
+*/
+
+// TODO: Needs modification to work with new codebase
+qx.Proto.clone = function(cloneRecursive, customPropertyList)
+{
+ var cloneInstance = new this.constructor;
+
+ var propertyName;
+ var propertyList = [];
+ var propertyIngoreList = this._clonePropertyIgnoreList.split(",");
+
+ // Build new filtered property list
+ var sourcePropertyList = qx.util.Validation.isValid(customPropertyList) ? customPropertyList : this._properties.split(",");
+ var sourcePropertyListLength = sourcePropertyList.length-1;
+ do {
+ propertyName = sourcePropertyList[sourcePropertyListLength];
+ if (!qx.lang.Array.contains(propertyIngoreList, propertyName)) {
+ propertyList.push(propertyName);
+ }
+ }
+ while(sourcePropertyListLength--);
+
+ // Apply properties to new clone instance
+ propertyListLength = propertyList.length-1;
+ do {
+ propertyName = qx.lang.String.toFirstUp(propertyList[propertyListLength]);
+ cloneInstance["set" + propertyName](this["get" + propertyName]());
+ }
+ while(propertyListLength--);
+
+ // post apply parent info
+ if (qx.lang.Array.contains(sourcePropertyList, "parent"))
+ {
+ var myParent = this.getParent();
+ if (myParent) {
+ cloneInstance.setParent(myParent);
+ }
+ }
+
+ // clone recursion
+ if (cloneRecursive) {
+ this._cloneRecursive(cloneInstance);
+ }
+
+ return cloneInstance;
+}
+
+qx.Proto._cloneRecursive = function(cloneInstance) {}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ COMMAND INTERFACE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.execute = function()
+{
+ var vCommand = this.getCommand();
+ if (vCommand) {
+ vCommand.execute(this);
+ }
+
+ this.createDispatchEvent("execute");
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ NODE ALIASES
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._visualPropertyCheck = function()
+{
+ if (!this.isCreated()) {
+ throw new Error("Element must be created previously!");
+ }
+}
+
+qx.Proto.setScrollLeft = function(nScrollLeft)
+{
+ this._visualPropertyCheck();
+ this._getTargetNode().scrollLeft = nScrollLeft;
+}
+
+qx.Proto.setScrollTop = function(nScrollTop)
+{
+ this._visualPropertyCheck();
+ this._getTargetNode().scrollTop = nScrollTop;
+}
+
+qx.Proto.getOffsetLeft = function()
+{
+ this._visualPropertyCheck();
+ return qx.dom.Offset.getLeft(this.getElement());
+}
+
+qx.Proto.getOffsetTop = function()
+{
+ this._visualPropertyCheck();
+ return qx.dom.Offset.getTop(this.getElement());
+}
+
+qx.Proto.getScrollLeft = function()
+{
+ this._visualPropertyCheck();
+ return this._getTargetNode().scrollLeft;
+}
+
+qx.Proto.getScrollTop = function()
+{
+ this._visualPropertyCheck();
+ return this._getTargetNode().scrollTop;
+}
+
+qx.Proto.getClientWidth = function()
+{
+ this._visualPropertyCheck();
+ return this._getTargetNode().clientWidth;
+}
+
+qx.Proto.getClientHeight = function()
+{
+ this._visualPropertyCheck();
+ return this._getTargetNode().clientHeight;
+}
+
+qx.Proto.getOffsetWidth = function()
+{
+ this._visualPropertyCheck();
+ return this.getElement().offsetWidth;
+}
+
+qx.Proto.getOffsetHeight = function()
+{
+ this._visualPropertyCheck();
+ return this.getElement().offsetHeight;
+}
+
+qx.Proto.getScrollWidth = function()
+{
+ this._visualPropertyCheck();
+ return this.getElement().scrollWidth;
+}
+
+qx.Proto.getScrollHeight = function()
+{
+ this._visualPropertyCheck();
+ return this.getElement().scrollHeight;
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ SCROLL INTO VIEW
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.scrollIntoView = function(vAlignTopLeft)
+{
+ this.scrollIntoViewX(vAlignTopLeft);
+ this.scrollIntoViewY(vAlignTopLeft);
+}
+
+qx.Proto.scrollIntoViewX = function(vAlignLeft)
+{
+ if (!this._isCreated || !this._isDisplayable) {
+ return false;
+ }
+
+ return qx.dom.ScrollIntoView.scrollX(this.getElement(), vAlignLeft);
+}
+
+qx.Proto.scrollIntoViewY = function(vAlignTop)
+{
+ if (!this._isCreated || !this._isDisplayable) {
+ return false;
+ }
+
+ return qx.dom.ScrollIntoView.scrollY(this.getElement(), vAlignTop);
+}
+
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DRAG AND DROP SUPPORT
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.supportsDrop = function(vDragCache) {
+ return true;
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ FADING PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ The amount of steps for the fade.
+ */
+qx.OO.addProperty({ name : 'fadeSteps', type : "number", allowNull : false, defaultValue : 10});
+/*!
+ The duration for the fade.
+ */
+qx.OO.addProperty({ name : 'fadeTime', type : "number", allowNull : false, defaultValue : 400});
+/*!
+ The time between the fade steps.
+ */
+qx.OO.addProperty({ name : 'fadeInterval', type : "number", allowNull : false, defaultValue : 40});
+/*!
+ The current state of a fade in progress.
+ */
+qx.OO.addProperty({ name : 'fadeCounter', type : "number", allowNull : false, defaultValue : 0});
+/*!
+ The amount of oppacity changed on each fade step.
+ */
+qx.OO.addProperty({ name : 'fadeUnit', type : "number", allowNull : false, defaultValue : 10});
+/*!
+ The maximum opacity for a fadeIn.
+ */
+qx.OO.addProperty({ name : 'fadeMax', type : "number", allowNull : false, defaultValue : 100});
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ FADING SUPPORT
+---------------------------------------------------------------------------
+*/
+qx.ui.core.Widget.FADE_IN = 'FADE_IN';
+qx.ui.core.Widget.FADE_OUT = 'FADE_OUT';
+qx.ui.core.Widget.FADE_FINISHED = 'FADE_FINISHED';
+
+
+qx.Proto.fadeIn = function(vSteps, vTime) {
+ if(vSteps) this.setFadeSteps(vSteps);
+ if(vTime) this.setFadeTime(vTime);
+ this._fadeMode = qx.ui.core.Widget.FADE_IN;
+ var timer = this.getFadeTimer();
+ timer.addEventListener("interval", this._onInterval, this);
+ timer.start();
+}
+
+qx.Proto.fadeOut = function(vSteps, vTime) {
+ if(vSteps) this.setFadeSteps(vSteps);
+ if(vTime) this.setFadeTime(vTime);
+ this._fadeMode = qx.ui.core.Widget.FADE_OUT;
+ var timer = this.getFadeTimer();
+ timer.addEventListener("interval", this._onInterval, this);
+ timer.start();
+};
+
+qx.Proto.getFadeTimer = function() {
+ if(this._fadeTimer){
+ this._fadeTimer.setInterval(this.getFadeInterval());
+ } else {
+ this._fadeTimer = new qx.client.Timer(this.getFadeInterval());
+ };
+ return this._fadeTimer;
+};
+
+qx.Proto.resetFader = function() {
+ this.setFadeCounter(0);
+ if(this.getFadeTimer()) {
+ this._fadeTimer.stop();
+ this._fadeTimer.dispose();
+ };
+ this._fadeTimer.dispose();
+ this._fadeTimer = null;
+};
+
+qx.Proto._onInterval = function(e) {
+ this.getFadeTimer().stop();
+ var counter = this.getFadeCounter();
+ switch (this._fadeMode){
+ case qx.ui.core.Widget.FADE_IN:
+ this.setFadeCounter(++counter);
+ if(counter <= this.getFadeSteps()){
+ this.setOpacity(this._computeFadeOpacity());
+ this.getFadeTimer().restart();
+ } else if(this.hasEventListeners(qx.ui.core.Widget.FADE_FINISHED)) {
+ this.createDispatchDataEvent(qx.ui.core.Widget.FADE_FINISHED, qx.ui.core.Widget.FADE_IN);
+ };
+ break;
+
+ case qx.ui.core.Widget.FADE_OUT:
+ this.setFadeCounter(--counter);
+ if(counter >= 0){
+ this.setOpacity(this._computeFadeOpacity());
+ this.getFadeTimer().restart();
+ } else if(this.hasEventListeners(qx.ui.core.Widget.FADE_FINISHED)) {
+ this.createDispatchDataEvent(qx.ui.core.Widget.FADE_FINISHED, qx.ui.core.Widget.FADE_OUT);
+ };
+ break;
+ };
+ qx.ui.core.Widget.flushGlobalQueues();
+};
+
+qx.Proto._modifyFadeSteps = function(propValue, propOldValue, propData) {
+ if(propValue < 1) return;
+ this.setFadeInterval(parseInt(this.getFadeTime() / propValue));
+ this.setFadeUnit(Math.round(this.getFadeMax()/propValue));
+ return true;
+};
+
+qx.Proto._modifyFadeTime = function(propValue, propOldValue, propData) {
+ if(propValue < 1) return;
+ this.setFadeInterval(parseInt(propValue / this.getFadeSteps()));
+ return true;
+};
+
+qx.Proto._modifyFadeUnit = function(propValue, propOldValue, propData) {
+ this.setFadeSteps(Math.round(this.getFadeMax()/propValue));
+ return true;
+};
+
+qx.Proto._modifyFadeMax = function(propValue, propOldValue, propData) {
+ this.setFadeUnit(Math.round(propValue / this.getFadeSteps()));
+ return true;
+};
+
+qx.Proto._computeFadeOpacity = function() {
+ var op = this.getFadeUnit() * this.getFadeCounter() / 100;
+ return(op);
+};
+
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPOSER
+---------------------------------------------------------------------------
+*/
+qx.Proto.dispose = function()
+{
+ if(this.getDisposed()) {
+ return;
+ }
+
+ var vElement = this.getElement();
+
+ if (vElement)
+ {
+ this._removeInlineEvents(vElement);
+
+ delete this._isCreated;
+
+ vElement.qx_Widget = null;
+
+ this._element = null;
+ this._style = null;
+ }
+
+ this._inlineEvents = null;
+ this._element = null;
+ this._style = null;
+ this._borderElement = null;
+ this._borderStyle = null;
+ this._oldParent = null;
+
+ // should be enough to remove the hashTables
+ delete this._styleProperties;
+ delete this._htmlProperties;
+ delete this._htmlAttributes;
+ delete this._states;
+
+ // remove queue content
+ for (var i in this._jobQueue) {
+ delete this._jobQueue[i];
+ }
+ delete this._jobQueue;
+
+ for (var i in this._layoutChanges) {
+ delete this._layoutChanges[i];
+ }
+ delete this._layoutChanges;
+
+ // dispose the fader
+ if(this._fadeTimer){
+ this._fadeTimer.dispose();
+ this._fadeTimer = null;
+ }
+
+ return qx.core.Target.prototype.dispose.call(this);
+}