diff options
Diffstat (limited to 'webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview')
10 files changed, 1721 insertions, 0 deletions
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellHtml.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellHtml.js new file mode 100644 index 0000000000..ed73e294cb --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellHtml.js @@ -0,0 +1,37 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.ContentCellHtml", qx.ui.embed.HtmlEmbed, +function(vHtml) +{ + qx.ui.embed.HtmlEmbed.call(this, vHtml); + + this.setSelectable(false); +}); + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view-content-cell-html" }); + +qx.ui.listview.ContentCellHtml.empty = { + html : "" +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellIconHtml.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellIconHtml.js new file mode 100644 index 0000000000..7203299e38 --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellIconHtml.js @@ -0,0 +1,39 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.ContentCellIconHtml", qx.ui.embed.IconHtmlEmbed, +function(vHtml, vIcon, vIconWidth, vIconHeight) +{ + qx.ui.embed.IconHtmlEmbed.call(this, vHtml, vIcon, vIconWidth, vIconHeight); + + this.setSelectable(false); +}); + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view-content-cell-icon-html" }); + +qx.ui.listview.ContentCellIconHtml.empty = +{ + icon : "", + html : "" +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellImage.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellImage.js new file mode 100644 index 0000000000..421f2e0f43 --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellImage.js @@ -0,0 +1,57 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.ContentCellImage", qx.ui.basic.Image, +function(vSource, vWidth, vHeight) { + qx.ui.basic.Image.call(this, vSource, vWidth, vHeight); +}); + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view-content-cell-image" }); + +qx.ui.listview.ContentCellImage.empty = { + source : "static/image/blank.gif" +} + + + +/* +--------------------------------------------------------------------------- + CUSTOM SETTER +--------------------------------------------------------------------------- +*/ + +qx.Proto.setSource = function(vSource) +{ + if (this._initialLayoutDone) + { + return this._updateContent(qx.manager.object.AliasManager.getInstance().resolvePath(vSource == "" ? "static/image/blank.gif" : vSource)); + } + else + { + return qx.ui.basic.Image.prototype.setSource.call(this, vSource); + } +} + +// Omit dimension setup in list-view +qx.Proto._postApplyDimensions = qx.util.Return.returnTrue; diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellLink.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellLink.js new file mode 100644 index 0000000000..b53338a595 --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellLink.js @@ -0,0 +1,40 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.ContentCellLink", qx.ui.embed.LinkEmbed, +function(vHtml) +{ + qx.ui.embed.LinkEmbed.call(this, vHtml); + + // selectable = false will break links in gecko based browsers + this.setSelectable(true); +}); + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view-content-cell-link" }); + +qx.ui.listview.ContentCellLink.empty = +{ + html : "", + uri : "#" +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellText.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellText.js new file mode 100644 index 0000000000..2d4b28544f --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ContentCellText.js @@ -0,0 +1,40 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.ContentCellText", qx.ui.embed.TextEmbed, +function(vText) +{ + qx.ui.embed.TextEmbed.call(this, vText); + + this.setStyleProperty("whiteSpace", "nowrap"); + this.setStyleProperty("textOverflow", "ellipsis"); + + this.setSelectable(false); +}); + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view-content-cell-text" }); + +qx.ui.listview.ContentCellText.empty = { + text : "" +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/Header.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/Header.js new file mode 100644 index 0000000000..5d11d5bdc0 --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/Header.js @@ -0,0 +1,294 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.Header", qx.ui.layout.HorizontalBoxLayout, +function(vColumns) +{ + qx.ui.layout.HorizontalBoxLayout.call(this); + + // This fixes the innerWidth calculation difference between the grid(pane) and the head. + this.setPaddingRight(qx.ui.core.Widget.SCROLLBAR_SIZE); + + + // ************************************************************************ + // STORE REFERENCE TO CONFIG ENTRY + // ************************************************************************ + this._columns = vColumns; + + + // ************************************************************************ + // CREATE HEADER CELLS + // ************************************************************************ + var vHeadCell, vHeadSeparator; + + for (var vCol in vColumns) + { + vHeadCell = new qx.ui.listview.HeaderCell(vColumns[vCol], vCol); + vHeadSeparator = new qx.ui.listview.HeaderSeparator; + + this.add(vHeadCell, vHeadSeparator); + + if (vColumns[vCol].align) { + vHeadCell.setHorizontalChildrenAlign(vColumns[vCol].align); + + if (vColumns[vCol].align == "right") { + vHeadCell.setReverseChildrenOrder(true); + } + } + + // store some additional data + vColumns[vCol].contentClass = qx.OO.classes["qx.ui.listview.ContentCell" + qx.lang.String.toFirstUp(vColumns[vCol].type || "text")]; + vColumns[vCol].headerCell = vHeadCell; + } + + + // ************************************************************************ + // ADD EVENT LISTENERS + // ************************************************************************ + this.addEventListener("mousemove", this._onmousemove); + this.addEventListener("mousedown", this._onmousedown); + this.addEventListener("mouseup", this._onmouseup); + this.addEventListener("mouseout", this._onmouseout); +}); + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view-header" }); + + + +/* +--------------------------------------------------------------------------- + RESIZE SYNC +--------------------------------------------------------------------------- +*/ + +qx.Proto._syncColumnWidth = function(vWidth) +{ + var vChildren = this.getChildren(); + var vColumn = Math.ceil(vChildren.indexOf(this._resizeCell) / 2); + + this.getParent().getPane().setColumnWidth(vColumn, vWidth); +} + +qx.Proto._syncResizeLine = function() +{ + qx.ui.core.Widget.flushGlobalQueues(); + + var vParent = this.getParent(); + var vLine = vParent.getResizeLine(); + var vLeft = qx.dom.Location.getPageBoxLeft(this._resizeSeparator.getElement()) - qx.dom.Location.getPageInnerLeft(this.getElement()); + var vTop = qx.dom.Dimension.getBoxHeight(vParent.getHeader().getElement()); + var vHeight = qx.dom.Dimension.getBoxHeight(vParent.getElement()) - vTop; + + vLine._applyRuntimeTop(vTop); + vLine._applyRuntimeHeight(vHeight); + vLine._applyRuntimeLeft(vLeft); + + vLine.removeStyleProperty("visibility"); +} + + + + +/* +--------------------------------------------------------------------------- + EVENT HANDLER +--------------------------------------------------------------------------- +*/ + +qx.Proto._mshtml = qx.sys.Client.getInstance().isMshtml(); + +qx.Proto._onmousemove = function(e) +{ + if (!this.getParent().getResizable()) { + return; + } + + if (this._resizingActive) + { + // Slow down mshtml a bit + if (this._mshtml) + { + if ((new Date).valueOf() - this._last < 50) { + return; + } + + this._last = (new Date).valueOf(); + } + + var vNewLeft = e.getPageX(); + var vSizeDiff = vNewLeft - this._resizeStart; + var vCell = this._resizeCell; + + vCell.setWidth(Math.max(4, vCell.getWidth() + vSizeDiff)); + this._resizeStart = vNewLeft; + + if (this.getParent().getLiveResize()) + { + this._syncColumnWidth(vCell._computeBoxWidth()); + } + else + { + this._syncResizeLine(); + } + } + else + { + var vTarget = e.getTarget(); + var vEventPos = e.getPageX(); + var vTargetPosLeft = qx.dom.Location.getPageBoxLeft(vTarget.getElement()); + var vTargetPosRight = vTargetPosLeft + qx.dom.Dimension.getBoxWidth(vTarget.getElement()); + + var vResizeCursor = false; + var vResizeSeparator = null; + + if (vTarget instanceof qx.ui.listview.HeaderSeparator) + { + vResizeCursor = true; + vResizeSeparator = vTarget; + } + else if ((vEventPos - vTargetPosLeft) <= 10) + { + // Ignore first column + if (!vTarget.isFirstChild()) + { + vResizeCursor = true; + vResizeSeparator = vTarget.getPreviousSibling(); + } + } + else if ((vTargetPosRight - vEventPos) <= 10) + { + vResizeCursor = true; + vResizeSeparator = vTarget.getNextSibling(); + } + + if (!(vResizeSeparator instanceof qx.ui.listview.HeaderSeparator)) + { + vResizeSeparator = vTarget = vResizeCursor = null; + } + + // Check if child is marked as resizable + else if (vResizeSeparator) + { + var vResizeCell = vResizeSeparator.getPreviousSibling(); + + if (vResizeCell && (vResizeCell._computedWidthTypePercent || vResizeCell._config.resizable == false)) { + vResizeSeparator = vTarget = vResizeCursor = null; + } + } + + // Apply global cursor + this.getTopLevelWidget().setGlobalCursor(vResizeCursor ? "e-resize" : null); + + // Store data for mousedown + this._resizeSeparator = vResizeSeparator; + this._resizeTarget = vTarget; + } +} + +qx.Proto._onmousedown = function(e) +{ + if (!this._resizeSeparator) { + return; + } + + this._resizingActive = true; + this._resizeStart = e.getPageX(); + this._resizeCell = this._resizeSeparator.getPreviousSibling(); + + if (!this.getParent().getLiveResize()) { + this._syncResizeLine(); + } + + this.setCapture(true); +} + +qx.Proto._onmouseup = function(e) +{ + if (!this._resizingActive) { + return; + } + + this._syncColumnWidth(this._resizeCell.getBoxWidth()); + + this.setCapture(false); + this.getTopLevelWidget().setGlobalCursor(null); + + // Remove hover effect + this._resizeTarget.removeState("over"); + + // Hide resize line + this.getParent().getResizeLine().setStyleProperty("visibility", "hidden"); + + this._cleanupResizing(); +} + +qx.Proto._onmouseout = function(e) +{ + if (!this.getCapture()) { + this.getTopLevelWidget().setGlobalCursor(null); + } +} + +qx.Proto._cleanupResizing = function() +{ + delete this._resizingActive; + + delete this._resizeSeparator; + delete this._resizeTarget; + delete this._resizeStart; + delete this._resizeCell; +} + + + + + + + + + + +/* +--------------------------------------------------------------------------- + DISPOSER +--------------------------------------------------------------------------- +*/ + +qx.Proto.dispose = function() +{ + if (this.getDisposed()) { + return; + } + + this._cleanupResizing(); + + this.removeEventListener("mousemove", this._onmousemove); + this.removeEventListener("mousedown", this._onmousedown); + this.removeEventListener("mouseup", this._onmouseup); + this.removeEventListener("mouseout", this._onmouseout); + + this._columns = null; + + return qx.ui.layout.HorizontalBoxLayout.prototype.dispose.call(this); +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/HeaderCell.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/HeaderCell.js new file mode 100644 index 0000000000..46e198b02b --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/HeaderCell.js @@ -0,0 +1,255 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.HeaderCell", qx.ui.basic.Atom, +function(vConfig, vId) +{ + qx.ui.basic.Atom.call(this, vConfig.label, vConfig.icon, vConfig.iconWidth, vConfig.iconHeight, vConfig.flash); + + // Text Overflow + this.setStyleProperty("textOverflow", "ellipsis"); + + + // ************************************************************************ + // STORE REFERENCE TO CONFIG ENTRY + // ************************************************************************ + this._config = vConfig; + this._id = vId; + + + // ************************************************************************ + // ARGUMENTS + // ************************************************************************ + this.setWidth(typeof vConfig.width === "undefined" ? "auto" : vConfig.width); + + if (qx.util.Validation.isValid(vConfig.minWidth)) { + this.setMinWidth(vConfig.minWidth); + } + + if (qx.util.Validation.isValid(vConfig.maxWidth)) { + this.setMaxWidth(vConfig.maxWidth); + } + + + // ************************************************************************ + // ADDITIONAL CHILDREN + // ************************************************************************ + + // Re-Enable flex support + this.getLayoutImpl().setEnableFlexSupport(true); + + this._spacer = new qx.ui.basic.HorizontalSpacer; + + this._arrowup = new qx.ui.basic.Image("widget/arrows/up.gif"); + this._arrowup.setVerticalAlign("middle"); + this._arrowup.setDisplay(false); + + this._arrowdown = new qx.ui.basic.Image("widget/arrows/down.gif"); + this._arrowdown.setVerticalAlign("middle"); + this._arrowdown.setDisplay(false); + + this.add(this._spacer, this._arrowup, this._arrowdown); + + + // ************************************************************************ + // EVENTS + // ************************************************************************ + + this.addEventListener("mouseup", this._onmouseup); + this.addEventListener("mouseover", this._onmouseover); + this.addEventListener("mouseout", this._onmouseout); +}); + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view-header-cell" }); +qx.OO.addProperty({ name : "sortOrder", type : "string", allowNull : true, possibleValues : [ "ascending", "descending" ] }); + +qx.Class.C_SORT_ASCENDING = "ascending"; +qx.Class.C_SORT_DESCENDING = "descending"; + + + +/* +--------------------------------------------------------------------------- + UTILITIES +--------------------------------------------------------------------------- +*/ + +qx.Proto.getView = function() { + return this.getParent().getParent(); +} + +qx.Proto.getNextSortOrder = function() +{ + var vCurrentSortOrder = this.getSortOrder(); + + switch(vCurrentSortOrder) + { + case qx.ui.listview.HeaderCell.C_SORT_ASCENDING: + return qx.ui.listview.HeaderCell.C_SORT_DESCENDING; + + default: + return qx.ui.listview.HeaderCell.C_SORT_ASCENDING; + } +} + +qx.Proto.updateSort = function() +{ + + var vListView = this.getView(); + var vData = vListView.getData(); + var vFieldId = this._id; + var vSortProp = this._config.sortProp || "text"; + var vSortMethod = this._config.sortMethod || qx.util.Compare.byString; + + vData.sort(function(a, b) { + return vSortMethod(a[vFieldId][vSortProp], b[vFieldId][vSortProp]); + }); + + if (this.getSortOrder() == qx.ui.listview.HeaderCell.C_SORT_DESCENDING) { + vData.reverse(); + } +} + + + + + +/* +--------------------------------------------------------------------------- + MODIFIER +--------------------------------------------------------------------------- +*/ + +qx.Proto._modifySortOrder = function(propValue, propOldValue, propData) +{ + var vListView = this.getView(); + + switch(propValue) + { + case qx.ui.listview.HeaderCell.C_SORT_ASCENDING: + this._arrowup.setDisplay(true); + this._arrowdown.setDisplay(false); + + vListView.setSortBy(this._id); + break; + + case qx.ui.listview.HeaderCell.C_SORT_DESCENDING: + this._arrowup.setDisplay(false); + this._arrowdown.setDisplay(true); + + vListView.setSortBy(this._id); + break; + + default: + this._arrowup.setDisplay(false); + this._arrowdown.setDisplay(false); + + if (vListView.getSortBy() == this._id) { + vListView.setSortBy(null); + } + } + + if (propValue) + { + this.updateSort(); + vListView.update(); + } + + return true; +} + + + + + + + +/* +--------------------------------------------------------------------------- + EVENT HANDLER +--------------------------------------------------------------------------- +*/ + +qx.Proto._onmouseover = function(e) { + this.addState("over"); +} + +qx.Proto._onmouseout = function(e) { + this.removeState("over"); +} + +qx.Proto._onmouseup = function(e) +{ + if (!this._config.sortable || this.getParent()._resizeSeparator) { + return; + } + + this.setSortOrder(this.getNextSortOrder()); + e.stopPropagation(); +} + + + + + + + +/* +--------------------------------------------------------------------------- + DISPOSER +--------------------------------------------------------------------------- +*/ + +qx.Proto.dispose = function() +{ + if (this.getDisposed()) { + return; + } + + delete this._config; + + if (this._spacer) + { + this._spacer.dispose(); + this._spacer = null; + } + + if (this._arrowup) + { + this._arrowup.dispose(); + this._arrowup = null; + } + + if (this._arrowdown) + { + this._arrowdown.dispose(); + this._arrowdown = null; + } + + this.removeEventListener("mouseup", this._onmouseup); + this.removeEventListener("mouseover", this._onmouseover); + this.removeEventListener("mouseout", this._onmouseout); + + return qx.ui.basic.Atom.prototype.dispose.call(this); +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/HeaderSeparator.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/HeaderSeparator.js new file mode 100644 index 0000000000..c2058db5d2 --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/HeaderSeparator.js @@ -0,0 +1,30 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.HeaderSeparator", qx.ui.basic.Terminator, +function() { + qx.ui.basic.Terminator.call(this); +}); + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view-header-separator" }); diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ListView.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ListView.js new file mode 100644 index 0000000000..567df4075e --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ListView.js @@ -0,0 +1,373 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.ListView", qx.ui.layout.VerticalBoxLayout, +function(vData, vColumns) +{ + // ************************************************************************ + // REFERENCES + // ************************************************************************ + + this._data = vData; + this._columns = vColumns; + + + + // ************************************************************************ + // OBJECTS + // ************************************************************************ + + this._header = new qx.ui.listview.Header(vColumns); + this._frame = new qx.ui.layout.HorizontalBoxLayout; + this._pane = new qx.ui.listview.ListViewPane(vData, vColumns); + this._scroll = new qx.ui.layout.CanvasLayout; + this._scrollContent = new qx.ui.basic.Terminator; + this._resizeLine = new qx.ui.basic.Terminator; + + + + // ************************************************************************ + // SUPERCLASS CONSTRUCTOR + // ************************************************************************ + + qx.ui.layout.VerticalBoxLayout.call(this); + + + + // ************************************************************************ + // HEADER + // ************************************************************************ + + this._header.setParent(this); + + + + // ************************************************************************ + // FRAME + // ************************************************************************ + + this._frame.setParent(this); + this._frame.setHeight("1*"); + this._frame.setWidth(null); + + + + // ************************************************************************ + // PANE + // ************************************************************************ + + this._pane.setParent(this._frame); + + + + // ************************************************************************ + // SCROLL AREA + // ************************************************************************ + + this._scroll.setWidth("auto"); + this._scroll.setOverflow("scrollY"); + this._scroll.setParent(this._frame); + this._scroll.enableInlineEvent("scroll"); + this._scroll.addEventListener("scroll", this._onscroll, this); + + + + // ************************************************************************ + // SCROLL CONTENT + // ************************************************************************ + + this._scrollContent.setWidth(1); + this._scrollContent.setParent(this._scroll); + + + + + // ************************************************************************ + // RESIZE LINE + // ************************************************************************ + + this._resizeLine.setBackgroundColor("#D6D5D9"); + this._resizeLine.setWidth(1); + this._resizeLine.setParent(this); + + + + // ************************************************************************ + // EVENTS + // ************************************************************************ + + this.addEventListener("mousedown", this._onmousedown); +}); + + + + +/* +--------------------------------------------------------------------------- + PROPERTIES +--------------------------------------------------------------------------- +*/ + +qx.OO.changeProperty({ name : "appearance", type : "string", defaultValue : "list-view" }); + +qx.OO.addProperty({ name : "resizable", type : "boolean", defaultValue : true }); +qx.OO.addProperty({ name : "liveResize", type : "boolean", defaultValue : false }); +qx.OO.addProperty({ name : "sortBy", type : "string" }); + + + + +/* +--------------------------------------------------------------------------- + UTILITIES +--------------------------------------------------------------------------- +*/ + +qx.Proto.getData = function() { + return this._data; +} + +qx.Proto.getColumns = function() { + return this._columns; +} + +qx.Proto.getHeader = function() { + return this._header; +} + +qx.Proto.getFrame = function() { + return this._frame; +} + +qx.Proto.getPane = function() { + return this._pane; +} + +qx.Proto.getScroll = function() { + return this._scroll; +} + +qx.Proto.getScrollContent = function() { + return this._scrollContent; +} + +qx.Proto.getResizeLine = function() { + return this._resizeLine; +} + +qx.Proto.update = function() +{ + this.updateScrollBar(); + this.updateContent(); + + // ignore updateLayout here, as it is mostly initially used +} + +qx.Proto.updateScrollBar = function() { + this._scrollContent.setHeight((this._data.length * this._pane._rowHeight) + this._pane._rowHeight); +} + +/*! + Bugfix for gecko 1.8 (the one released with firefox 1.5) + Overflow updates if content gets smaller are problematic + https://bugzilla.mozilla.org/show_bug.cgi?id=320106 +*/ +if (qx.sys.Client.getInstance().isGecko() && qx.sys.Client.getInstance().getVersion() >= 1.8) +{ + qx.Proto._updateScrollBar = qx.Proto.updateScrollBar; + + qx.Proto.updateScrollBar = function() + { + this._updateScrollBar(); + + this._scroll.setStyleProperty("height", "0px"); + this._scroll.forceHeight(0); + this._scroll.setHeight(null); + } +} + +qx.Proto.updateContent = function() { + this.getPane()._updateRendering(true); +} + +qx.Proto.updateLayout = function() { + this.getPane()._updateLayout(); +} + +qx.Proto.updateSort = function() +{ + var vSortBy = this.getSortBy(); + + if (!vSortBy) { + return; + } + + var vCell = this._getHeaderCell(vSortBy); + + if (vCell) { + vCell.updateSort(); + } +} + +qx.Proto._getHeaderCell = function(vCellId) +{ + var vNewEntry = this._columns[vCellId]; + return vNewEntry ? vNewEntry.headerCell : null; +} + + + + + + +/* +--------------------------------------------------------------------------- + MODIFIERS +--------------------------------------------------------------------------- +*/ + +qx.Proto._modifySortBy = function(propValue, propOldValue, propData) +{ + if (propOldValue) + { + var vOldCell = this._getHeaderCell(propOldValue); + + if (vOldCell) { + vOldCell.setSortOrder(null); + } + } + + if (propValue) + { + var vNewCell = this._getHeaderCell(propValue); + + if (vNewCell && vNewCell.getSortOrder() == null) { + vNewCell.setSortOrder(qx.ui.listview.HeaderCell.C_SORT_ASCENDING); + } + } + + return true; +} + + + + + + +/* +--------------------------------------------------------------------------- + EVENT HANDLER +--------------------------------------------------------------------------- +*/ + +qx.Proto._onscroll = function(e) { + this._pane._onscroll(e); +} + +qx.Proto._onmousedown = function(e) { + this.getFocusRoot().setActiveChild(this.getPane()); +} + + + + + + +/* +--------------------------------------------------------------------------- + DISPLAYBLE HANDLING +--------------------------------------------------------------------------- +*/ + +qx.Proto._handleDisplayableCustom = function(vDisplayable, vParent, vHint) +{ + qx.ui.layout.VerticalBoxLayout.prototype._handleDisplayableCustom.call(this, vDisplayable, vParent, vHint); + + if (vDisplayable) + { + this.updateLayout(); + this.updateScrollBar(); + this.updateContent(); + } +} + + + + + +/* +--------------------------------------------------------------------------- + DISPOSER +--------------------------------------------------------------------------- +*/ + +qx.Proto.dispose = function() +{ + if (this.getDisposed()) { + return; + } + + if (this._header) + { + this._header.dispose(); + this._header = null; + } + + if (this._frame) + { + this._frame.dispose(); + this._frame = null; + } + + if (this._pane) + { + this._pane.dispose(); + this._pane = null; + } + + if (this._scroll) + { + this._scroll.dispose(); + this._scroll = null; + } + + if (this._scrollContent) + { + this._scrollContent.dispose(); + this._scrollContent = null; + } + + if (this._resizeLine) + { + this._resizeLine.dispose(); + this._resizeLine = null; + } + + delete this._columns; + delete this._data; + + this.removeEventListener("mousedown", this._onmousedown); + + return qx.ui.layout.VerticalBoxLayout.prototype.dispose.call(this); +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ListViewPane.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ListViewPane.js new file mode 100644 index 0000000000..89ae3c6fea --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/listview/ListViewPane.js @@ -0,0 +1,556 @@ +/* ************************************************************************ + + 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_listview) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.listview.ListViewPane", qx.ui.layout.GridLayout, +function(vData, vColumns) +{ + qx.ui.layout.GridLayout.call(this); + + // ************************************************************************ + // DATA + // ************************************************************************ + // Add aliases for data tables + this._data = vData; + this._columns = vColumns; + + + // ************************************************************************ + // INITIALIZE MANAGER + // ************************************************************************ + this._manager = new qx.manager.selection.VirtualSelectionManager(this); + + + // ************************************************************************ + // MOUSE EVENT LISTENER + // ************************************************************************ + // Add handling for mouse wheel events + // Needed because the virtual scroll area does not fire browser + // understandable events above this pane. + this.addEventListener("mousewheel", this._onmousewheel); + + this.addEventListener("mouseover", this._onmouseover); + this.addEventListener("mousedown", this._onmousedown); + this.addEventListener("mouseup", this._onmouseup); + this.addEventListener("click", this._onclick); + this.addEventListener("dblclick", this._ondblclick); + + + // ************************************************************************ + // KEY EVENT LISTENER + // ************************************************************************ + this.addEventListener("keypress", this._onkeypress); +}); + +qx.OO.changeProperty({ name : "appearance", + type : "string", + defaultValue : "list-view-pane" + }); + +qx.Proto._rowHeight = 16; + + + + + + +/* +--------------------------------------------------------------------------- + UTILITIES +--------------------------------------------------------------------------- +*/ + +qx.Proto.getView = function() { + return this.getParent().getParent(); +} + + + + + + +/* +--------------------------------------------------------------------------- + UPDATER +--------------------------------------------------------------------------- +*/ + +qx.Proto._lastRowCount = 0; + +qx.Proto._updateLayout = function(vUpdate) +{ + // this.debug("InnerHeight: " + this._computeInnerHeight()); + // this.debug("BoxHeight: " + this._computeBoxHeight()); + // return + + var vColumns = this._columns; + var vRowCount = Math.ceil(this.getInnerHeight() / this._rowHeight); + var vData = this._data; + var vCell; + + // this.debug("Row-Count: " + this._lastRowCount + " => " + vRowCount); + + // Sync cells: Add new ones and configure them + if (vRowCount > this._lastRowCount) + { + for (var i=this._lastRowCount, j=0; i<vRowCount; i++, j=0) + { + for (var vCol in vColumns) + { + vCell = new vColumns[vCol].contentClass; + + this.add(vCell, j++, i); + + if (vColumns[vCol].align) { + vCell.setStyleProperty("textAlign", + vColumns[vCol].align); + } + } + } + } + + // Sync cells: Remove existing ones and dispose them + else if (this._lastRowCount > vRowCount) + { + var vChildren = this.getChildren(); + var vChildrenLength = vChildren.length - 1; + + for (var i=this._lastRowCount; i>vRowCount; i--) + { + for (var vCol in vColumns) + { + vCell = vChildren[vChildrenLength--]; + this.remove(vCell); + vCell.dispose(); + } + } + } + + // Update row and column count + this.setRowCount(vRowCount); + if (!vUpdate) { + this.setColumnCount(qx.lang.Object.getLength(vColumns)); + } + + // Apply height to all rows + for (var i=0; i<vRowCount; i++) { + this.setRowHeight(i, this._rowHeight); + } + + if (!vUpdate) + { + // Apply width and alignment to all columns + var vCount = 0; + for (var vCol in vColumns) + { + this.setColumnHorizontalAlignment(vCount, vColumns[vCol].align); + this.setColumnWidth(vCount, vColumns[vCol].width); + + vCount++; + } + } + + // Store last row count + this._lastRowCount = vRowCount; +} + +qx.Proto._currentScrollTop = -1; + +qx.Proto._updateRendering = function(vForce) +{ + if (this._updatingRendering) { + return; + } + + var vScrollTop = (this._initialLayoutDone + ? this.getView().getScroll().getScrollTop() + : 0); + + this._updatingRendering = true; + this._currentScrollTop = vScrollTop; + + for (var i=0; i<this._rowCount; i++) { + this._updateRow(i); + } + + delete this._updatingRendering; +} + +qx.Proto._updateRow = function(vRelativeRow) +{ + var vData = this._data; + var vRowOffset = Math.floor(this._currentScrollTop / this._rowHeight); + + var vColumnCount = this.getColumnCount(); + var vColumns = this._columns; + + var vChildren = this.getVisibleChildren(); + var vChild, vEntry, vCol; + + var j=0; + + for (vCol in vColumns) + { + vEntry = vData[vRowOffset+vRelativeRow]; + vChild = vChildren[vColumnCount*vRelativeRow+(j++)]; + + if (vChild) + { + if (vEntry && vEntry._selected) { + vChild.addState("selected"); + } else { + vChild.removeState("selected"); + } + vChild.set(vEntry + ? vEntry[vCol] + : vColumns[vCol].empty || vColumns[vCol].contentClass.empty); + } + } +} + +qx.Proto._onscroll = function(e) { + this._updateRendering(); +} + + + + + +/* +--------------------------------------------------------------------------- + DIMENSION CACHE +--------------------------------------------------------------------------- +*/ + +qx.Proto._changeInnerHeight = function(vNew, vOld) +{ + this._updateLayout(true); + this._updateRendering(true); + + return qx.ui.layout.GridLayout.prototype._changeInnerHeight.call(this, + vNew, + vOld); +} + + + + + + +/* +--------------------------------------------------------------------------- + MANAGER BINDING +--------------------------------------------------------------------------- +*/ + +qx.Proto.getManager = function() { + return this._manager; +} + +qx.Proto.getListViewTarget = function(e) +{ + var vEventTop = e.getPageY(); + var vPaneTop = qx.dom.Location.getPageInnerTop(this.getElement()); + var vItemNo = Math.floor(this._currentScrollTop / this._rowHeight) + + Math.floor((vEventTop - vPaneTop) / this._rowHeight); + + return this._data[vItemNo]; +} + +qx.Proto.getSelectedItem = function() { + return this.getSelectedItems()[0]; +} + +qx.Proto.getSelectedItems = function() { + return this._manager.getSelectedItems(); +} + +qx.Proto.getData = function() { + return this._data; +} + +// use static row height +qx.Proto.getItemHeight = function(vItem) { + return this._rowHeight; +} + +// use the full inner width of the pane +qx.Proto.getItemWidth = function(vItem) { + return qx.dom.Dimension.getInnerWidth(this.getElement()); +} + +qx.Proto.getItemLeft = function(vItem) { + return 0; +} + +qx.Proto.getItemTop = function(vItem) { + return this._data.indexOf(vItem) * this._rowHeight; +} + + + + +/* +--------------------------------------------------------------------------- + MOUSE EVENT HANDLER +--------------------------------------------------------------------------- +*/ + +qx.Proto._onmousewheel = function(e) +{ + var vScroll = this.getView().getScroll(); + vScroll.setScrollTop(vScroll.getScrollTop() - (e.getWheelDelta() * 20)); +} + +qx.Proto._onmouseover = function(e) +{ + var vTarget = this.getListViewTarget(e); + if (vTarget) { + this._manager.handleMouseOver(vTarget, e); + } +} + +qx.Proto._onmousedown = function(e) +{ + var vTarget = this.getListViewTarget(e); + if (vTarget) { + this._manager.handleMouseDown(vTarget, e); + } +} + +qx.Proto._onmouseup = function(e) +{ + var vTarget = this.getListViewTarget(e); + if (vTarget) { + this._manager.handleMouseUp(vTarget, e); + } +} + +qx.Proto._onclick = function(e) +{ + var vTarget = this.getListViewTarget(e); + if (vTarget) { + this._manager.handleClick(vTarget, e); + } +} + +qx.Proto._ondblclick = function(e) +{ + var vTarget = this.getListViewTarget(e); + if (vTarget) { + this._manager.handleDblClick(vTarget, e); + } +} + + + + + + +/* +--------------------------------------------------------------------------- + KEY EVENT HANDLER +--------------------------------------------------------------------------- +*/ + +qx.Proto._onkeypress = function(e) +{ + this._manager.handleKeyPress(e); + e.preventDefault(); +} + + + + + + +/* +--------------------------------------------------------------------------- + MANAGER SELECTION +--------------------------------------------------------------------------- +*/ + +qx.Proto._updateSelectionState = function(vItem, vIsSelected) +{ + vItem._selected = vIsSelected; + this._updateItem(vItem); +} + +qx.Proto._updateAnchorState = function(vItem, vIsAnchor) +{ + vItem._anchor = vIsAnchor; + this._updateItem(vItem); +} + +qx.Proto._updateLeadState = function(vItem, vIsLead) +{ + vItem._lead = vIsLead; + this._updateItem(vItem); +} + +qx.Proto.scrollItemIntoView = function(vItem, vAlignLeftTop) +{ + this.scrollItemIntoViewX(vItem, vAlignLeftTop); + this.scrollItemIntoViewY(vItem, vAlignLeftTop); +} + +qx.Proto.scrollItemIntoViewX = function(vItem, vAlignLeft) { + // this.error("Not implemented in qx.ui.listview.ListViewPane!"); +} + +qx.Proto.scrollItemIntoViewY = function(vItem, vAlignTop) +{ + var vItems = this._data; + var vOffset = vItems.indexOf(vItem) * this._rowHeight; + var vHeight = this._rowHeight; + + // normalize client height (we want that the item is fully visible) + var vParentHeight = (Math.floor(this.getClientHeight() / this._rowHeight) * + this._rowHeight); + var vParentScrollTop = this._currentScrollTop; + + var vNewScrollTop = null; + + if (vAlignTop) + { + vNewScrollTop = vOffset; + } + else if (vAlignTop == false) + { + vNewScrollTop = vOffset + vHeight - vParentHeight; + } + else if (vHeight > vParentHeight || vOffset < vParentScrollTop) + { + vNewScrollTop = vOffset; + } + else if ((vOffset + vHeight) > (vParentScrollTop + vParentHeight)) + { + vNewScrollTop = vOffset + vHeight - vParentHeight; + } + + if (vNewScrollTop != null) { + this.getView().getScroll().setScrollTop(vNewScrollTop); + } +} + +qx.Proto.setScrollTop = function(vScrollTop) +{ + this.getView().getScroll().setScrollTop(vScrollTop); + this._updateRendering(); +} + +qx.Proto.getScrollTop = function() { + return this._currentScrollTop; +} + +qx.Proto.setScrollLeft = function() { + this.error("Not implemented in qx.ui.listview.ListViewPane!"); +} + +qx.Proto.getScrollLeft = function() { + return 0; +} + +qx.Proto.isItemVisible = function(vItem) +{ + var vIndex = this._data.indexOf(vItem); + var vRowStart = Math.floor(this._currentScrollTop / this._rowHeight); + var vRowLength = Math.ceil(this.getClientHeight() / this._rowHeight); + + return vIndex >= vRowStart && vIndex <= (vRowStart + vRowLength); +} + +qx.Proto.getRelativeItemPosition = function(vItem) +{ + var vIndex = this._data.indexOf(vItem); + var vRowStart = Math.floor(this._currentScrollTop / this._rowHeight); + + return vIndex - vRowStart; +} + +qx.Proto._updateItem = function(vItem) +{ + var vIndex = this._data.indexOf(vItem); + var vRowStart = Math.floor(this._currentScrollTop / this._rowHeight); + var vRowLength = Math.ceil(this.getClientHeight() / this._rowHeight); + + if (vIndex < vRowStart || vIndex > (vRowStart + vRowLength)) { + return; + } + + this._updateRow(vIndex - vRowStart); +} + + + + + + +/* +--------------------------------------------------------------------------- + DISPOSER +--------------------------------------------------------------------------- +*/ + +qx.Proto.dispose = function() +{ + if (this.getDisposed()) { + return; + } + + + // ************************************************************************ + // MOUSE EVENT LISTENER + // ************************************************************************ + this.removeEventListener("mousewheel", this._onmousewheel); + this.removeEventListener("mouseover", this._onmouseover); + this.removeEventListener("mousedown", this._onmousedown); + this.removeEventListener("mouseup", this._onmouseup); + this.removeEventListener("click", this._onclick); + this.removeEventListener("dblclick", this._ondblclick); + + + // ************************************************************************ + // KEY EVENT LISTENER + // ************************************************************************ + this.removeEventListener("keypress", this._onkeypress); + + + // ************************************************************************ + // DATA + // ************************************************************************ + delete this._data; + delete this._columns; + + + // ************************************************************************ + // MANAGER + // ************************************************************************ + if (this._manager) + { + this._manager.dispose(); + this._manager = null; + } + + return qx.ui.layout.GridLayout.prototype.dispose.call(this); +} |