From: Matti Tahvonen Date: Fri, 29 Jun 2007 10:00:18 +0000 (+0000) Subject: implemented column ordrering, not even hitting server X-Git-Tag: 6.7.0.beta1~6201 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=06f57f4c8227b32c119f5933373b6dc8f8b2f98a;p=vaadin-framework.git implemented column ordrering, not even hitting server svn changeset:1802/svn branch:trunk --- diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTable.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTable.java index 4da8715f9f..98225395e2 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTable.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTable.java @@ -2,7 +2,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui.scrolltable; import java.util.HashMap; import java.util.Iterator; -import java.util.Map; +import java.util.Vector; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; @@ -12,14 +12,11 @@ import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.FlowPanel; -import com.google.gwt.user.client.ui.Grid; -import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.ScrollListener; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.user.client.ui.HTMLTable.CellFormatter; import com.itmill.toolkit.terminal.gwt.client.Client; import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.UIDL; @@ -51,7 +48,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll private boolean initializedAndAttached = false; - private Grid tHead = new Grid(1,1); + private TableHead tHead = new TableHead(); private ScrollPanel bodyContainer = new ScrollPanel(); @@ -160,36 +157,34 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll if(uidl == null) return; int columnCount = uidl.getChidlCount(); - if(rowHeaders) + int colIndex = 0; + if(rowHeaders) { columnCount++; - tHead.resizeColumns(columnCount); + HeaderCell c = (HeaderCell) tHead.getHeaderCell(0); + if(c == null) { + tHead.setHeaderCell(0, new HeaderCell("0", "")); + } + colIndex++; + } for(Iterator it = uidl.getChildIterator();it.hasNext();) { UIDL col = (UIDL) it.next(); String cid = col.getStringAttribute("cid"); - int colIndex = getColIndexByKey(cid); - if(colIndex > -1) { - HeaderCell c = (HeaderCell) tHead.getWidget(0, colIndex); - if(c != null && c.getColKey().equals(cid)) { - c.setText(col.getStringAttribute("caption")); - } else { - c = new HeaderCell(cid, col.getStringAttribute("caption")); - tHead.setWidget(0, colIndex, c ); - } - if(col.hasAttribute("sortable")) { - c.setSortable(true); - if(cid.equals(sortColumn)) - c.setSorted(true); - else - c.setSorted(false); - } + HeaderCell c = (HeaderCell) tHead.getHeaderCell(colIndex); + if(c != null && c.getColKey().equals(cid)) { + c.setText(col.getStringAttribute("caption")); + } else { + c = new HeaderCell(cid, col.getStringAttribute("caption")); + tHead.setHeaderCell(colIndex, c); } - } - if(rowHeaders) { - HeaderCell c = (HeaderCell) tHead.getWidget(0, 0); - if(c == null) { - tHead.setWidget(0, 0, new HeaderCell("0", "")); + if(col.hasAttribute("sortable")) { + c.setSortable(true); + if(cid.equals(sortColumn)) + c.setSorted(true); + else + c.setSorted(false); } + colIndex++; } } @@ -219,15 +214,27 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll private int getColIndexByKey(String colKey) { - return Integer.parseInt(colKey) - 1 + (rowHeaders ? 1 : 0); + // return 0 if asked for rowHeaders + if("0".equals(colKey)) + return 0; + int index = -1; + for (int i = 0; i < columnOrder.length; i++) { + if(columnOrder[i].equals(colKey)) { + index = i; + break; + } + } + if(rowHeaders) + index++; + return index; } private String getColKeyByIndex(int index) { - return ((HeaderCell) tHead.getWidget(0, index)).getColKey(); + return tHead.getHeaderCell(index).getColKey(); } private void setColWidth(int colIndex, int w) { - HeaderCell cell = (HeaderCell) tHead.getWidget(0, colIndex); + HeaderCell cell = tHead.getHeaderCell(colIndex); cell.setWidth(w); tBody.setColWidth(colIndex, w); String cid = cell.getColKey();; @@ -241,6 +248,33 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll private int getRenderedRowCount() { return tBody.getLastRendered()-tBody.getFirstRendered(); } + + private void reOrderColumn(String columnKey, int newIndex) { + + int oldIndex = getColIndexByKey(columnKey); + + // Change header order + tHead.moveCell(oldIndex, newIndex); + + // Change body order + tBody.moveCol(oldIndex, newIndex); + + // build new columnOrder and update it to server + + String[] newOrder = new String[columnOrder.length]; + + Iterator hCells = tHead.iterator(); + + if(rowHeaders) + hCells.next(); + int index = 0; + while(hCells.hasNext()) { + newOrder[index++] = ((HeaderCell) hCells.next()).getColKey(); + } + columnOrder = newOrder; + client.updateVariable(id, "columnorder", newOrder, false); + + } /** * This method has logick which rows needs to be requested from @@ -305,6 +339,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll protected void onAttach() { super.onAttach(); + int bodyWidth = tBody.getOffsetWidth(); // sync column widths initColumnWidths(); @@ -316,6 +351,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll } if(width < 0) { + bodyWidth = tBody.getOffsetWidth(); bodyContainer.setWidth((tBody.getOffsetWidth() + getScrollBarWidth() ) + "px"); headerContainer.setWidth((tBody.getOffsetWidth()) + "px"); } else { @@ -323,6 +359,8 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll headerContainer.setWidth(width + "px"); } + tHead.disableBrowserIntelligence(); + if(firstvisible > 0) bodyContainer.setScrollPosition(firstvisible*tBody.getRowHeight()); @@ -345,15 +383,16 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll * "natural widths and saves the values. */ private void initColumnWidths() { - int cols = tHead.getCellCount(0); - CellFormatter hf = tHead.getCellFormatter(); - for (int i = 0; i < cols; i++) { - Element hCell = hf.getElement(0, i); - int hw = DOM.getIntAttribute(hCell, "offsetWidth"); - int cw = tBody.getColWidth(i); - int w = (hw > cw ? hw : cw) + IScrollTableBody.CELL_EXTRA_WIDTH; - setColWidth(i , w); - } + Iterator headCells = tHead.iterator(); + int i = 0; + while(headCells.hasNext()) { + Element hCell = ((HeaderCell) headCells.next()).getElement(); + int hw = DOM.getIntAttribute(hCell, "offsetWidth"); + int cw = tBody.getColWidth(i); + int w = (hw > cw ? hw : cw) + IScrollTableBody.CELL_EXTRA_WIDTH; + setColWidth(i , w); + i++; + } } private int getScrollBarWidth() { @@ -406,10 +445,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll private static final int MINIMUM_COL_WIDTH = 20; - // TODO create a simple single row table widget that has these widgets as cells - // and change next line to ...DOM.createTD(); - // Grid is way too overkill for this and it removes on extra div from document structure - Element td = DOM.createDiv(); + Element td = DOM.createTD(); Element captionContainer = DOM.createDiv(); @@ -429,6 +465,8 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll private boolean moved; + private int closestSlot; + private HeaderCell(){}; @@ -531,6 +569,7 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll case Event.ONMOUSEDOWN: dragging = true; moved = false; + colIndex = getColIndexByKey(cid); DOM.setCapture(getElement()); System.out.println("Started column reordering"); this.headerX = tHead.getAbsoluteLeft(); @@ -539,7 +578,18 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll break; case Event.ONMOUSEUP: dragging = false; + if(!moved) { + // sort + break; + } System.out.println("Stopped column reordering"); + tHead.removeSlotFocus(); + if(closestSlot != colIndex && closestSlot != (colIndex + 1) ) { + if(closestSlot > colIndex) + reOrderColumn(cid, closestSlot - 1); + else + reOrderColumn(cid, closestSlot); + } DOM.releaseCapture(getElement()); break; case Event.ONMOUSEMOVE: @@ -548,25 +598,25 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll System.out.print("Dragging column, optimal index..."); int x = DOM.eventGetClientX(event); int slotX = headerX; - int closestIndex = 0; + closestSlot = colIndex; int closestDistance = -1; int start = 0; if(rowHeaders) { start++; - slotX += getColWidth(getColKeyByIndex(0)); } - for(int i = start ; i < columnWidths.size(); i++ ) { - String colKey = getColKeyByIndex(i); + for(int i = start; i <= columnWidths.size() ; i++ ) { + if(i > 0) { + String colKey = getColKeyByIndex(i-1); + slotX += getColWidth(colKey); + } int dist = Math.abs(x - slotX); if(closestDistance == -1 || dist < closestDistance) { closestDistance = dist; - closestIndex = i; + closestSlot = i; } - slotX += getColWidth(colKey); } - focusSlot(closestIndex); - System.out.println(closestIndex); - + tHead.focusSlot(closestSlot); + System.out.println(closestSlot); } break; default: @@ -574,17 +624,6 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll } } - private void focusSlot(int slot) { - // TODO consider some workaround for this - removeSlotFocus(); - DOM.setStyleAttribute(tHead.getCellFormatter().getElement(0, slot), "borderLeft", "2px solid black"); - } - - private void removeSlotFocus() { - for(int i = 0; i < tHead.getColumnCount();i++) - DOM.setStyleAttribute(tHead.getCellFormatter().getElement(0, i), "borderLeft", "none"); - } - private int getClosestColumnIndex(int x) { return 1; } @@ -623,4 +662,91 @@ public class IScrollTable extends Composite implements Paintable, ITable, Scroll } + public class TableHead extends Panel { + + private static final int WRAPPER_WIDTH = 9000; + + Vector cells = new Vector(); + + Element div = DOM.createDiv(); + Element table = DOM.createTable(); + Element tBody = DOM.createTBody(); + Element tr = DOM.createTR(); + + private int focusedSlot = -1; + + public TableHead() { + DOM.appendChild(table, tBody); + DOM.appendChild(tBody, tr); + DOM.appendChild(div, table); + setElement(div); + } + + public void disableBrowserIntelligence() { + DOM.setStyleAttribute(div, "width", WRAPPER_WIDTH +"px"); + } + + public void setHeaderCell(int index, HeaderCell cell) { + if(index < cells.size()) { + // replace + // TODO remove old correctly + // insert to right slot + } else if( index == cells.size()) { + //append + adopt(cell, tr); + cells.add(cell); + } else { + throw new RuntimeException("Header cells must be appended in order"); + } + } + + public HeaderCell getHeaderCell(int index) { + if(index < cells.size()) + return (HeaderCell) cells.get(index); + else + return null; + } + + public void moveCell(int oldIndex, int newIndex) { + HeaderCell hCell = getHeaderCell(oldIndex); + Element cell = hCell.getElement(); + + cells.remove(oldIndex); + DOM.removeChild(tr, cell); + + DOM.insertChild(tr, cell, newIndex); + cells.insertElementAt(hCell, newIndex); + } + + public Iterator iterator() { + return cells.iterator(); + } + + public boolean remove(Widget w) { + // TODO Auto-generated method stub + return false; + } + + private void focusSlot(int index) { + removeSlotFocus(); + if(index > 0) + DOM.setStyleAttribute(DOM.getChild(tr, index - 1), "borderRight", "2px solid black"); + else + DOM.setStyleAttribute(DOM.getChild(tr, index), "borderLeft", "2px solid black"); + focusedSlot = index; + } + + private void removeSlotFocus() { + if(focusedSlot < 0) + return; + if(focusedSlot == 0) + DOM.setStyleAttribute(DOM.getChild(tr, focusedSlot), "borderLeft", "none"); + else if( focusedSlot > 0) + DOM.setStyleAttribute(DOM.getChild(tr, focusedSlot - 1), "borderRight", "none"); + focusedSlot = -1; + } + + + } + } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableBody.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableBody.java index 0f5da2d6a3..7c16552d32 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableBody.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableBody.java @@ -236,5 +236,22 @@ public class IScrollTableBody extends Panel { public int getFirstRendered() { return firstRendered; } + + public void moveCol(int oldIndex, int newIndex) { + + // loop all rows and move given index to its new place + Iterator rows = iterator(); + while(rows.hasNext()) { + IScrollTableRow row = (IScrollTableRow) rows.next(); + + Element td = DOM.getChild(row.getElement(), oldIndex); + DOM.removeChild(row.getElement(), td); + + DOM.insertChild(row.getElement(), td, newIndex); + + } + + } + }