You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by no...@apache.org on 2009/11/13 11:04:18 UTC
svn commit: r835797 -
/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraListViewSkin.java
Author: noelgrandin
Date: Fri Nov 13 10:04:17 2009
New Revision: 835797
URL: http://svn.apache.org/viewvc?rev=835797&view=rev
Log:
apply changes suggested by Greg Brown
- used array for caching item heights
- move height calculation to layout()
Modified:
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraListViewSkin.java
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraListViewSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraListViewSkin.java?rev=835797&r1=835796&r2=835797&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraListViewSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraListViewSkin.java Fri Nov 13 10:04:17 2009
@@ -21,6 +21,7 @@
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Transparency;
+import java.util.Arrays;
import org.apache.pivot.collections.ArrayList;
import org.apache.pivot.collections.Dictionary;
@@ -64,9 +65,8 @@
private Color highlightBackgroundColor;
private boolean showHighlight;
private boolean variableItemHeight;
- private ArrayList<Integer> variableItemHeightYCache = new ArrayList<Integer>();
- /* I can work out all of the heights from the YCache except for the last one */
- private int variableItemLastHeight;
+ private int [] variableItemHeightYCache;
+ private int fixedItemHeight;
private Insets checkboxPadding = new Insets(2, 2, 2, 0);
private int highlightedIndex = -1;
@@ -136,21 +136,21 @@
ListView listView = (ListView)getComponent();
List<Object> listData = (List<Object>)listView.getListData();
ListView.ItemRenderer itemRenderer = listView.getItemRenderer();
-
+
if (variableItemHeight) {
int clientWidth = width;
if (listView.getCheckmarksEnabled()) {
clientWidth = Math.max(clientWidth - (CHECKBOX.getWidth() + (checkboxPadding.left
+ checkboxPadding.right)), 0);
}
-
+
int index = 0;
for (Object item : listData) {
itemRenderer.render(item, index++, listView, false, false, false, false);
preferredHeight += itemRenderer.getPreferredHeight(clientWidth);
}
} else {
- preferredHeight = listData.getLength() * getFixedItemHeight();
+ preferredHeight = listData.getLength() * fixedItemHeight;
}
return preferredHeight;
@@ -171,7 +171,7 @@
ListView.ItemRenderer itemRenderer = listView.getItemRenderer();
List<Object> listData = (List<Object>)listView.getListData();
- if (variableItemHeight && listData.getLength()>0) {
+ if (variableItemHeight && listData.getLength() > 0) {
itemRenderer.render(listData.get(0), 0, listView, false, false, false, false);
int itemHeight = itemRenderer.getPreferredHeight(clientWidth);
if (listView.getCheckmarksEnabled()) {
@@ -182,15 +182,72 @@
baseline = itemRenderer.getBaseline(clientWidth, itemHeight);
} else {
itemRenderer.render(null, -1, listView, false, false, false, false);
- baseline = itemRenderer.getBaseline(clientWidth, getFixedItemHeight());
+ baseline = itemRenderer.getBaseline(clientWidth, fixedItemHeight);
}
return baseline;
}
@Override
+ @SuppressWarnings("unchecked")
public void layout() {
- // No-op
+ ListView listView = (ListView)getComponent();
+ List<Object> listData = (List<Object>)listView.getListData();
+ ListView.ItemRenderer itemRenderer = listView.getItemRenderer();
+
+ if (variableItemHeight) {
+
+ int width = getWidth();
+
+ // Paint the list contents
+ int itemEnd = listData.getLength() - 1;
+
+ int checkboxHeight = 0;
+ if (listView.getCheckmarksEnabled()) {
+ checkboxHeight = CHECKBOX.getHeight() + (checkboxPadding.top
+ + checkboxPadding.bottom);
+ }
+
+ variableItemHeightYCache = new int[listData.getLength() + 1];
+ int itemY = 0;
+
+ for (int itemIndex = 0; itemIndex <= itemEnd; itemIndex++) {
+ Object item = listData.get(itemIndex);
+ boolean highlighted = (itemIndex == highlightedIndex
+ && listView.getSelectMode() != ListView.SelectMode.NONE);
+ boolean selected = listView.isItemSelected(itemIndex);
+ boolean disabled = listView.isItemDisabled(itemIndex);
+
+ int itemWidth = width;
+ int itemX = 0;
+
+ boolean checked = false;
+ if (listView.getCheckmarksEnabled()) {
+ checked = listView.isItemChecked(itemIndex);
+ itemX = CHECKBOX.getWidth() + (checkboxPadding.left
+ + checkboxPadding.right);
+ itemWidth -= itemX;
+ }
+
+ itemRenderer.render(item, itemIndex, listView, selected, checked, highlighted, disabled);
+ int itemHeight = itemRenderer.getPreferredHeight(itemWidth);
+ if (listView.getCheckmarksEnabled()) {
+ itemHeight = Math.max(itemHeight, checkboxHeight);
+ }
+
+ variableItemHeightYCache[itemIndex] = itemY;
+ itemY += itemHeight;
+ }
+ variableItemHeightYCache[listData.getLength()] = itemY;
+ } else {
+ itemRenderer.render(null, -1, listView, false, false, false, false);
+
+ fixedItemHeight = itemRenderer.getPreferredHeight(-1);
+ if (listView.getCheckmarksEnabled()) {
+ fixedItemHeight = Math.max(CHECKBOX.getHeight() + (checkboxPadding.top
+ + checkboxPadding.bottom), fixedItemHeight);
+ }
+ }
}
@Override
@@ -208,13 +265,7 @@
graphics.setPaint(backgroundColor);
graphics.fillRect(0, 0, width, height);
}
-
- if (variableItemHeight) {
- paintVariableItemHeight(graphics);
- return;
- }
-
- int itemHeight = getFixedItemHeight();
+
// Paint the list contents
int itemStart = 0;
int itemEnd = listData.getLength() - 1;
@@ -222,18 +273,36 @@
// Ensure that we only paint items that are visible
Rectangle clipBounds = graphics.getClipBounds();
if (clipBounds != null) {
- itemStart = Math.max(itemStart, (int)Math.floor(clipBounds.y
- / (double)itemHeight));
- itemEnd = Math.min(itemEnd, (int)Math.ceil((clipBounds.y
- + clipBounds.height) / (double)itemHeight) - 1);
+ if (variableItemHeight) {
+ itemStart = getItemAt(clipBounds.y);
+ itemEnd = getItemAt(clipBounds.y + clipBounds.height - 1);
+ } else {
+ itemStart = Math.max(itemStart, (int)Math.floor(clipBounds.y
+ / (double)fixedItemHeight));
+ itemEnd = Math.min(itemEnd, (int)Math.ceil((clipBounds.y
+ + clipBounds.height) / (double)fixedItemHeight) - 1);
+ }
}
+ int itemY;
+ if (variableItemHeight) {
+ itemY = variableItemHeightYCache[itemStart];
+ } else {
+ itemY = itemStart * fixedItemHeight;
+ }
+
for (int itemIndex = itemStart; itemIndex <= itemEnd; itemIndex++) {
Object item = listData.get(itemIndex);
boolean highlighted = (itemIndex == highlightedIndex
&& listView.getSelectMode() != ListView.SelectMode.NONE);
boolean selected = listView.isItemSelected(itemIndex);
boolean disabled = listView.isItemDisabled(itemIndex);
+ int itemHeight;
+ if (variableItemHeight) {
+ itemHeight = variableItemHeightYCache[itemIndex + 1] - variableItemHeightYCache[itemIndex];
+ } else {
+ itemHeight = fixedItemHeight;
+ }
Color itemBackgroundColor = null;
@@ -248,11 +317,10 @@
if (itemBackgroundColor != null) {
graphics.setPaint(itemBackgroundColor);
- graphics.fillRect(0, itemIndex * itemHeight, width, itemHeight);
+ graphics.fillRect(0, itemY, width, itemHeight);
}
int itemX = 0;
- int itemY = itemIndex * itemHeight;
int itemWidth = width;
boolean checked = false;
@@ -282,110 +350,11 @@
itemRenderer.setSize(itemWidth, itemHeight);
itemRenderer.paint(rendererGraphics);
rendererGraphics.dispose();
- }
- }
-
- @SuppressWarnings("unchecked")
- private void paintVariableItemHeight(Graphics2D graphics) {
- ListView listView = (ListView)getComponent();
- List<Object> listData = (List<Object>)listView.getListData();
- ListView.ItemRenderer itemRenderer = listView.getItemRenderer();
-
- int width = getWidth();
-
- // Paint the list contents
- int itemEnd = listData.getLength() - 1;
-
- // Ensure that we only paint items that are visible
- Rectangle clipBounds = graphics.getClipBounds();
-
- int checkboxHeight = 0;
- if (listView.getCheckmarksEnabled()) {
- checkboxHeight = CHECKBOX.getHeight() + (checkboxPadding.top
- + checkboxPadding.bottom);
- }
-
- // if we haven't initialised the cache, we need to paint everything
- boolean computeCache = variableItemHeightYCache.getLength() != listData.getLength();
- int itemY = 0;
-
- for (int itemIndex = 0; itemIndex <= itemEnd; itemIndex++) {
- if (!computeCache && clipBounds!=null && itemY > clipBounds.y + clipBounds.height) {
- break;
- }
- Object item = listData.get(itemIndex);
- boolean highlighted = (itemIndex == highlightedIndex
- && listView.getSelectMode() != ListView.SelectMode.NONE);
- boolean selected = listView.isItemSelected(itemIndex);
- boolean disabled = listView.isItemDisabled(itemIndex);
-
- int itemWidth = width;
- int itemX = 0;
-
- boolean checked = false;
- if (listView.getCheckmarksEnabled()) {
- checked = listView.isItemChecked(itemIndex);
- itemX = CHECKBOX.getWidth() + (checkboxPadding.left
- + checkboxPadding.right);
- itemWidth -= itemX;
- }
-
- itemRenderer.render(item, itemIndex, listView, selected, checked, highlighted, disabled);
- int itemHeight = itemRenderer.getPreferredHeight(itemWidth);
- if (listView.getCheckmarksEnabled()) {
- itemHeight = Math.max(itemHeight, checkboxHeight);
- }
-
- boolean paintItem = true;
- if (clipBounds != null) {
- paintItem = (itemY + itemHeight) >= clipBounds.y && itemY < (clipBounds.y + clipBounds.height);
- }
- if (paintItem) {
- Color itemBackgroundColor = null;
-
- if (selected) {
- itemBackgroundColor = (listView.isFocused())
- ? this.selectionBackgroundColor : inactiveSelectionBackgroundColor;
- } else {
- if (highlighted && showHighlight && !disabled) {
- itemBackgroundColor = highlightBackgroundColor;
- }
- }
-
- if (itemBackgroundColor != null) {
- graphics.setPaint(itemBackgroundColor);
- graphics.fillRect(0, itemY, width, itemHeight);
- }
-
- if (listView.getCheckmarksEnabled()) {
- int checkboxY = (itemHeight - CHECKBOX.getHeight()) / 2;
- Graphics2D checkboxGraphics = (Graphics2D)graphics.create(checkboxPadding.left,
- itemY + checkboxY, CHECKBOX.getWidth(), CHECKBOX.getHeight());
-
- CHECKBOX.setSelected(checked);
- CHECKBOX.setEnabled(!disabled && !listView.isCheckmarkDisabled(itemIndex));
- CHECKBOX.paint(checkboxGraphics);
- checkboxGraphics.dispose();
- }
-
- // Paint the data
- Graphics2D rendererGraphics = (Graphics2D)graphics.create(itemX, itemY,
- itemWidth, itemHeight);
-
- itemRenderer.setSize(itemWidth, itemHeight);
- itemRenderer.paint(rendererGraphics);
- rendererGraphics.dispose();
- }
-
- if (computeCache) {
- variableItemHeightYCache.add(itemY);
- variableItemLastHeight = itemHeight;
- }
+
itemY += itemHeight;
}
}
-
// List view skin methods
@Override
@SuppressWarnings("unchecked")
@@ -398,13 +367,12 @@
int index;
if (variableItemHeight) {
- index = ArrayList.binarySearch(variableItemHeightYCache, y);
- if (index<0) {
- index = -index-2;
-
+ index = Arrays.binarySearch(variableItemHeightYCache, y);
+ if (index < 0) {
+ index = -index - 2;
}
} else {
- index = (y / getFixedItemHeight());
+ index = (y / fixedItemHeight);
}
List<Object> listData = (List<Object>)listView.getListData();
if (index >= listData.getLength()) {
@@ -419,15 +387,11 @@
int itemY;
int itemHeight;
if (variableItemHeight) {
- itemY = variableItemHeightYCache.get(index);
- if (index < variableItemHeightYCache.getLength() - 1) {
- itemHeight = variableItemHeightYCache.get(index+1) - itemY;
- } else {
- itemHeight = variableItemLastHeight;
- }
+ itemY = variableItemHeightYCache[index];
+ itemHeight = variableItemHeightYCache[index + 1] - itemY;
} else {
- itemHeight = getFixedItemHeight();
- itemY = index * itemHeight;
+ itemY = index * fixedItemHeight;
+ itemHeight = fixedItemHeight;
}
return new Bounds(0, itemY, getWidth(), itemHeight);
}
@@ -444,20 +408,26 @@
return itemIndent;
}
- private int getFixedItemHeight() {
- ListView listView = (ListView)getComponent();
- ListView.ItemRenderer itemRenderer = listView.getItemRenderer();
- itemRenderer.render(null, -1, listView, false, false, false, false);
-
- int itemHeight = itemRenderer.getPreferredHeight(-1);
- if (listView.getCheckmarksEnabled()) {
- itemHeight = Math.max(CHECKBOX.getHeight() + (checkboxPadding.top
- + checkboxPadding.bottom), itemHeight);
+ private int getItemY(int index) {
+ int itemY;
+ if (variableItemHeight) {
+ itemY = variableItemHeightYCache[index];
+ } else {
+ itemY = index * fixedItemHeight;
+ }
+ return itemY;
+ }
+
+ private int getItemHeight(int index) {
+ int itemHeight;
+ if (variableItemHeight) {
+ itemHeight = variableItemHeightYCache[index + 1] - variableItemHeightYCache[index];
+ } else {
+ itemHeight = fixedItemHeight;
}
-
return itemHeight;
}
-
+
@Override
public boolean isFocusable() {
ListView listView = (ListView)getComponent();
@@ -727,7 +697,7 @@
setCheckboxPadding(Insets.decode(checkboxPadding));
}
- public boolean getVariableItemHeight() {
+ public boolean isVariableItemHeight() {
return variableItemHeight;
}
@@ -736,7 +706,7 @@
repaintComponent();
}
-
+
@Override
public boolean mouseMove(Component component, int x, int y) {
boolean consumed = super.mouseMove(component, x, y);
@@ -788,7 +758,7 @@
int itemIndex = getItemAt(y);
- if (itemIndex != -1
+ if (itemIndex != -1
&& itemIndex < listData.getLength()
&& !listView.isItemDisabled(itemIndex)) {
int itemY = getItemBounds(itemIndex).y;
@@ -1023,13 +993,13 @@
// List view events
@Override
public void listDataChanged(ListView listView, List<?> previousListData) {
- variableItemHeightYCache.clear();
+ variableItemHeightYCache = null;
invalidateComponent();
}
@Override
public void itemRendererChanged(ListView listView, ListView.ItemRenderer previousItemRenderer) {
- variableItemHeightYCache.clear();
+ variableItemHeightYCache = null;
invalidateComponent();
}
@@ -1045,7 +1015,7 @@
@Override
public void checkmarksEnabledChanged(ListView listView) {
- variableItemHeightYCache.clear();
+ variableItemHeightYCache = null;
invalidateComponent();
}
@@ -1073,31 +1043,31 @@
// List view item events
@Override
public void itemInserted(ListView listView, int index) {
- variableItemHeightYCache.clear();
+ variableItemHeightYCache = null;
invalidateComponent();
}
@Override
public void itemsRemoved(ListView listView, int index, int count) {
- variableItemHeightYCache.clear();
+ variableItemHeightYCache = null;
invalidateComponent();
}
@Override
public void itemUpdated(ListView listView, int index) {
- variableItemHeightYCache.clear();
+ variableItemHeightYCache = null;
invalidateComponent();
}
@Override
public void itemsCleared(ListView listView) {
- variableItemHeightYCache.clear();
+ variableItemHeightYCache = null;
invalidateComponent();
}
@Override
public void itemsSorted(ListView listView) {
- variableItemHeightYCache.clear();
+ variableItemHeightYCache = null;
if (variableItemHeight) {
invalidateComponent();
} else {
@@ -1114,32 +1084,42 @@
// List view selection detail events
@Override
public void selectedRangeAdded(ListView listView, int rangeStart, int rangeEnd) {
- if (variableItemHeight) {
- repaintComponent();
- } else {
- // Repaint the area containing the added selection
- int itemHeight = getFixedItemHeight();
- repaintComponent(0, rangeStart * itemHeight,
- getWidth(), (rangeEnd - rangeStart + 1) * itemHeight);
- }
+ // Repaint the area containing the added selection
+ repaintComponent(0, getItemY(rangeStart),
+ getWidth(), getItemY(rangeEnd) + getItemHeight(rangeEnd));
}
@Override
public void selectedRangeRemoved(ListView listView, int rangeStart, int rangeEnd) {
- if (variableItemHeight) {
- repaintComponent();
- } else {
- // Repaint the area containing the removed selection
- int itemHeight = getFixedItemHeight();
- repaintComponent(0, rangeStart * itemHeight,
- getWidth(), (rangeEnd - rangeStart + 1) * itemHeight);
- }
+ // Repaint the area containing the removed selection
+ repaintComponent(0, getItemY(rangeStart),
+ getWidth(), getItemY(rangeEnd) + getItemHeight(rangeEnd));
}
@Override
+ @SuppressWarnings("unchecked")
public void selectedRangesChanged(ListView listView, Sequence<Span> previousSelectedRanges) {
- // TODO Repaint only the area that changed (intersection of previous
+ List<Object> listData = (List<Object>)listView.getListData();
+
+ // Repaint only the area that changed (intersection of previous
// and new selection)
- repaintComponent();
+
+ int rangeStart = 0;
+ int rangeEnd = listData.getLength() - 1;
+ for (int i = 0; i < previousSelectedRanges.getLength(); i++) {
+ Span span = previousSelectedRanges.get(i);
+ rangeStart = Math.min(rangeStart, span.start);
+ rangeEnd = Math.max(rangeEnd, span.end);
+ }
+
+ Sequence<Span> newSelectedRanges = listView.getSelectedRanges();
+ for (int i = 0; i < newSelectedRanges.getLength(); i++) {
+ Span span = newSelectedRanges.get(i);
+ rangeStart = Math.min(rangeStart, span.start);
+ rangeEnd = Math.max(rangeEnd, span.end);
+ }
+
+ repaintComponent(0, getItemY(rangeStart),
+ getWidth(), getItemY(rangeEnd) + getItemHeight(rangeEnd));
}
}