You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/03/17 23:21:51 UTC
svn commit: r755425 -
/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraTreeViewSkin.java
Author: tvolkert
Date: Tue Mar 17 22:21:50 2009
New Revision: 755425
URL: http://svn.apache.org/viewvc?rev=755425&view=rev
Log:
Added more logic towards full checkbox support in TerraTreeViewskin
Modified:
incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraTreeViewSkin.java
Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraTreeViewSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraTreeViewSkin.java?rev=755425&r1=755424&r2=755425&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraTreeViewSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraTreeViewSkin.java Tue Mar 17 22:21:50 2009
@@ -53,22 +53,35 @@
/**
* An internal data structure that keeps track of skin-related metadata
- * for a tree node.
+ * for a tree node. The justification for the existence of this class lies
+ * in the <tt>visibleNodes</tt> data structure, which is a flat list of
+ * nodes that are visible at any given time. In this context, visible means
+ * that their parent hierarchy is expanded, <b>not</b> that they are being
+ * painted. This list, combined with <tt>getNodeHeight()</tt>, enables us
+ * to quickly determine which nodes to paint given a graphics clip rect.
+ * It also enables us to quickly traverse the tree view when handling key
+ * events.
* <p>
- * NOTE some of this data is duplicated from <tt>TreeView</tt> to provide
- * optimizations during painting and user input.
+ * NOTE: some of this data is managed by <tt>TreeView</tt> and cached here
+ * to provide further optimizations during painting and user input.
*
* @author tvolkert
*/
protected static class NodeInfo {
+ // Core skin metadata
private BranchInfo parent;
-
public Object data;
public int depth;
- public boolean selected = false;
public boolean highlighted = false;
- public boolean disabled = false;
- public TreeView.NodeCheckState checkState = TreeView.NodeCheckState.UNCHECKED;
+
+ // Cached fields. Note that this is maintained as a bitmask in favor of
+ // separate properties because it allows us to easily clear any cached
+ // field for all nodes in one common method. See #clearField(byte)
+ protected byte fieldCache = 0;
+
+ public static final byte SELECTED_MASK = 1 << 0;
+ public static final byte DISABLED_MASK = 1 << 1;
+ public static final byte CHECK_STATE_MASK = 3 << 2;
public NodeInfo(BranchInfo parent, Object data) {
this.parent = parent;
@@ -106,6 +119,66 @@
return path;
}
+
+ public boolean isSelected() {
+ return ((fieldCache & SELECTED_MASK) != 0);
+ }
+
+ public void setSelected(boolean selected) {
+ if (selected) {
+ fieldCache |= SELECTED_MASK;
+ } else {
+ fieldCache &= ~SELECTED_MASK;
+ }
+ }
+
+ public boolean isDisabled() {
+ return ((fieldCache & DISABLED_MASK) != 0);
+ }
+
+ public void setDisabled(boolean disabled) {
+ if (disabled) {
+ fieldCache |= DISABLED_MASK;
+ } else {
+ fieldCache &= ~DISABLED_MASK;
+ }
+ }
+
+ public TreeView.NodeCheckState getCheckState() {
+ TreeView.NodeCheckState checkState;
+
+ int checkStateBits = (fieldCache & CHECK_STATE_MASK) >> 2;
+ switch (checkStateBits) {
+ case 0:
+ checkState = TreeView.NodeCheckState.UNCHECKED;
+ break;
+ case 1:
+ checkState = TreeView.NodeCheckState.CHECKED;
+ break;
+ default:
+ checkState = TreeView.NodeCheckState.MIXED;
+ break;
+ }
+
+ return checkState;
+ }
+
+ public void setCheckState(TreeView.NodeCheckState checkState) {
+ fieldCache &= ~CHECK_STATE_MASK;
+
+ switch (checkState) {
+ case CHECKED:
+ fieldCache |= (1 << 2);
+ break;
+ case MIXED:
+ fieldCache |= (1 << 3);
+ break;
+ }
+ }
+
+ public void clearField(byte mask) {
+ fieldCache &= ~mask;
+ }
}
/**
@@ -115,13 +188,23 @@
* @author tvolkert
*/
protected static class BranchInfo extends NodeInfo {
+ // Core skin metadata
public Sequence<NodeInfo> children = null;
- public boolean expanded = false;
+
+ public static final byte EXPANDED_MASK = 1 << 4;
public BranchInfo(BranchInfo parent, List<Object> data) {
super(parent, data);
}
+ /**
+ * Loads this branch info's children. The children list is initialized
+ * to <tt>null</tt> and loaded lazily to allow the skin to only create
+ * <tt>NodeInfo</tt> objects for the nodes that it actually needs in
+ * order to paint. Thus, it is the responsibility of the skin to check
+ * if <tt>children</tt> is null and call <tt>loadChildren()</tt> if
+ * necessary.
+ */
@SuppressWarnings("unchecked")
public void loadChildren() {
if (children == null) {
@@ -136,6 +219,18 @@
}
}
}
+
+ public boolean isExpanded() {
+ return ((fieldCache & EXPANDED_MASK) != 0);
+ }
+
+ public void setExpanded(boolean expanded) {
+ if (expanded) {
+ fieldCache |= EXPANDED_MASK;
+ } else {
+ fieldCache &= ~EXPANDED_MASK;
+ }
+ }
}
private BranchInfo rootBranchInfo = null;
@@ -143,6 +238,7 @@
private NodeInfo highlightedNode = null;
+ // Styles
private Font font;
private Color color;
private Color disabledColor;
@@ -169,9 +265,11 @@
private static final int VERTICAL_SPACING = 1;
private static final Checkbox CHECKBOX = new Checkbox();
+ private static final int CHECKBOX_VERTICAL_PADDING = 2;
static {
- CHECKBOX.setSize(CHECKBOX.getPreferredSize());
+ CHECKBOX.setSize(CHECKBOX.getPreferredSize());
+ CHECKBOX.setTriState(true);
}
public TerraTreeViewSkin() {
@@ -234,14 +332,6 @@
int nodeWidth = (nodeInfo.depth - 1) * (indent + spacing);
- if (showBranchControls) {
- nodeWidth += indent + spacing;
- }
-
- if (treeView.getCheckmarksEnabled()) {
- nodeWidth += indent + spacing;
- }
-
nodeRenderer.render(nodeInfo.data, treeView, false, false,
TreeView.NodeCheckState.UNCHECKED, false, false);
nodeWidth += nodeRenderer.getPreferredWidth(-1);
@@ -249,6 +339,14 @@
preferredWidth = Math.max(preferredWidth, nodeWidth);
}
+ if (showBranchControls) {
+ preferredWidth += indent + spacing;
+ }
+
+ if (treeView.getCheckmarksEnabled()) {
+ preferredWidth += Math.max(CHECKBOX.getWidth(), indent) + spacing;
+ }
+
return preferredWidth;
}
@@ -308,8 +406,8 @@
boolean expanded = false;
boolean highlighted = nodeInfo.highlighted;
- boolean selected = nodeInfo.selected;
- boolean disabled = nodeInfo.disabled;
+ boolean selected = nodeInfo.isSelected();
+ boolean disabled = nodeInfo.isDisabled();
int nodeX = (nodeInfo.depth - 1) * (indent + spacing);
@@ -331,7 +429,7 @@
if (showBranchControls) {
if (nodeInfo instanceof BranchInfo) {
BranchInfo branchInfo = (BranchInfo)nodeInfo;
- expanded = branchInfo.expanded;
+ expanded = branchInfo.isExpanded();
Color branchControlColor;
@@ -380,11 +478,15 @@
// Paint the checkbox
TreeView.NodeCheckState checkState = TreeView.NodeCheckState.UNCHECKED;
if (treeView.getCheckmarksEnabled()) {
- checkState = nodeInfo.checkState;
+ checkState = nodeInfo.getCheckState();
+
+ int checkboxWidth = CHECKBOX.getWidth();
+ int checkboxHeight = CHECKBOX.getHeight();
- int checkboxY = (nodeHeight - CHECKBOX.getHeight()) / 2;
- Graphics2D checkboxGraphics = (Graphics2D)graphics.create(nodeX,
- nodeY + checkboxY, CHECKBOX.getWidth(), CHECKBOX.getHeight());
+ int checkboxX = Math.max(indent - checkboxWidth, 0) / 2;
+ int checkboxY = (nodeHeight - checkboxHeight) / 2;
+ Graphics2D checkboxGraphics = (Graphics2D)graphics.create(nodeX + checkboxX,
+ nodeY + checkboxY, checkboxWidth, checkboxHeight);
Button.State state;
switch (checkState) {
@@ -399,11 +501,11 @@
break;
}
- CHECKBOX.setState(state);
- CHECKBOX.paint(checkboxGraphics);
- checkboxGraphics.dispose();
+ CHECKBOX.setState(state);
+ CHECKBOX.paint(checkboxGraphics);
+ checkboxGraphics.dispose();
- nodeX += indent + spacing;
+ nodeX += Math.max(indent, checkboxWidth) + spacing;
}
int nodeWidth = width - nodeX;
@@ -471,6 +573,11 @@
setColor(decodeColor(color));
}
+ public final void setColor(int color) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setColor(theme.getColor(color));
+ }
+
public Color getDisabledColor() {
return disabledColor;
}
@@ -492,6 +599,11 @@
setDisabledColor(decodeColor(disabledColor));
}
+ public final void setDisabledColor(int disabledColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setDisabledColor(theme.getColor(disabledColor));
+ }
+
public Color getBackgroundColor() {
return backgroundColor;
}
@@ -513,6 +625,11 @@
setBackgroundColor(decodeColor(backgroundColor));
}
+ public final void setBackgroundColor(int backgroundColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setBackgroundColor(theme.getColor(backgroundColor));
+ }
+
public Color getSelectionColor() {
return selectionColor;
}
@@ -534,6 +651,11 @@
setSelectionColor(decodeColor(selectionColor));
}
+ public final void setSelectionColor(int selectionColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setSelectionColor(theme.getColor(selectionColor));
+ }
+
public Color getSelectionBackgroundColor() {
return selectionBackgroundColor;
}
@@ -555,6 +677,11 @@
setSelectionBackgroundColor(decodeColor(selectionBackgroundColor));
}
+ public final void setSelectionBackgroundColor(int selectionBackgroundColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setSelectionBackgroundColor(theme.getColor(selectionBackgroundColor));
+ }
+
public Color getInactiveSelectionColor() {
return inactiveSelectionColor;
}
@@ -576,6 +703,11 @@
setInactiveSelectionColor(decodeColor(inactiveSelectionColor));
}
+ public final void setInactiveSelectionColor(int inactiveSelectionColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setInactiveSelectionColor(theme.getColor(inactiveSelectionColor));
+ }
+
public Color getInactiveSelectionBackgroundColor() {
return inactiveSelectionBackgroundColor;
}
@@ -597,6 +729,11 @@
setInactiveSelectionBackgroundColor(decodeColor(inactiveSelectionBackgroundColor));
}
+ public final void setInactiveSelectionBackgroundColor(int inactiveSelectionBackgroundColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setInactiveSelectionBackgroundColor(theme.getColor(inactiveSelectionBackgroundColor));
+ }
+
public Color getHighlightColor() {
return highlightColor;
}
@@ -618,6 +755,11 @@
setHighlightColor(decodeColor(highlightColor));
}
+ public final void setHighlightColor(int highlightColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setHighlightColor(theme.getColor(highlightColor));
+ }
+
public Color getHighlightBackgroundColor() {
return highlightBackgroundColor;
}
@@ -639,6 +781,11 @@
setHighlightBackgroundColor(decodeColor(highlightBackgroundColor));
}
+ public final void setHighlightBackgroundColor(int highlightBackgroundColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setHighlightBackgroundColor(theme.getColor(highlightBackgroundColor));
+ }
+
public int getSpacing() {
return spacing;
}
@@ -712,6 +859,11 @@
setBranchControlColor(decodeColor(branchControlColor));
}
+ public final void setBranchControlColor(int branchControlColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setBranchControlColor(theme.getColor(branchControlColor));
+ }
+
public Color getBranchControlDisabledColor() {
return branchControlDisabledColor;
}
@@ -733,6 +885,11 @@
setBranchControlDisabledColor(decodeColor(branchControlDisabledColor));
}
+ public final void setBranchControlDisabledColor(int branchControlDisabledColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setBranchControlDisabledColor(theme.getColor(branchControlDisabledColor));
+ }
+
public Color getBranchControlSelectionColor() {
return branchControlSelectionColor;
}
@@ -754,6 +911,11 @@
setBranchControlSelectionColor(decodeColor(branchControlSelectionColor));
}
+ public final void setBranchControlSelectionColor(int branchControlSelectionColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setBranchControlSelectionColor(theme.getColor(branchControlSelectionColor));
+ }
+
public Color getBranchControlInactiveSelectionColor() {
return branchControlInactiveSelectionColor;
}
@@ -775,6 +937,11 @@
setBranchControlInactiveSelectionColor(decodeColor(branchControlInactiveSelectionColor));
}
+ public final void setBranchControlInactiveSelectionColor(int branchControlInactiveSelectionColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setBranchControlInactiveSelectionColor(theme.getColor(branchControlInactiveSelectionColor));
+ }
+
public Color getGridColor() {
return gridColor;
}
@@ -796,6 +963,11 @@
setGridColor(decodeColor(gridColor));
}
+ public final void setGridColor(int gridColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setGridColor(theme.getColor(gridColor));
+ }
+
public boolean getShowGridLines() {
return showGridLines;
}
@@ -812,7 +984,13 @@
TreeView treeView = (TreeView)getComponent();
TreeView.NodeRenderer nodeRenderer = treeView.getNodeRenderer();
- return nodeRenderer.getPreferredHeight(-1);
+ int nodeHeight = nodeRenderer.getPreferredHeight(-1);
+
+ if (treeView.getCheckmarksEnabled()) {
+ nodeHeight = Math.max(CHECKBOX.getHeight() + (2 * CHECKBOX_VERTICAL_PADDING), nodeHeight);
+ }
+
+ return nodeHeight;
}
/**
@@ -835,6 +1013,7 @@
/**
* Gets the metadata associated with the node at the specified path.
+ * The path must be valid.
*/
protected NodeInfo getNodeInfoAt(Sequence<Integer> path) {
assert(path != null) : "Path is null";
@@ -885,6 +1064,9 @@
/**
* Adds all children of the specified branch to the visible node list.
+ * Any children nodes that are expanded [branches] will also have their
+ * children made visible, and so on. Invalidates the component only
+ * if necessary.
*/
private void addVisibleNodes(BranchInfo parentBranchInfo) {
int insertIndex = -1;
@@ -911,7 +1093,7 @@
while (nodes.getLength() > 0) {
NodeInfo nodeInfo = nodes.get(0);
- nodes.remove(nodeInfo);
+ nodes.remove(0, 1);
visibleNodes.insert(nodeInfo, insertIndex++);
@@ -920,7 +1102,7 @@
if (nodeInfo instanceof BranchInfo) {
BranchInfo branchInfo = (BranchInfo)nodeInfo;
- if (branchInfo.expanded) {
+ if (branchInfo.isExpanded()) {
branchInfo.loadChildren();
for (int i = 0, n = branchInfo.children.getLength(); i < n; i++) {
nodes.insert(branchInfo.children.get(i), i);
@@ -928,14 +1110,21 @@
}
}
}
- }
- invalidateComponent();
+ invalidateComponent();
+ }
}
/**
* Adds the specified child of the specified branch to the visible node
- * list.
+ * list. It is assumed that the child in question is not an expanded
+ * branch. Invalidates the component only if necessary.
+ *
+ * @param parentBranchInfo
+ * The branch info of the parent node.
+ *
+ * @param index
+ * The index of the child within its parent.
*/
private void addVisibleNode(BranchInfo parentBranchInfo, int index) {
parentBranchInfo.loadChildren();
@@ -945,8 +1134,8 @@
int branchIndex = visibleNodes.indexOf(parentBranchInfo);
- if ((branchIndex >= 0 && parentBranchInfo.expanded)
- || parentBranchInfo == rootBranchInfo) {
+ if (parentBranchInfo == rootBranchInfo
+ || (branchIndex >= 0 && parentBranchInfo.isExpanded())) {
NodeInfo nodeInfo = parentBranchInfo.children.get(index);
@@ -970,26 +1159,26 @@
}
visibleNodes.insert(nodeInfo, insertIndex);
- }
- invalidateComponent();
+ invalidateComponent();
+ }
}
/**
* Removes the specified children of the specified branch from the visible
* node list if necessary. If they are not already in the visible node
- * list, nothing happens.
+ * list, nothing happens. Invalidates the component only if necessary.
*
* @param parentBranchInfo
- * The branch info of the parent node
+ * The branch info of the parent node.
*
* @param index
* The index of the first child node to remove from the visible nodes
- * sequence
+ * sequence.
*
* @param count
* The number of child nodes to remove, or <tt>-1</tt> to remove all
- * child nodes from the visible nodes sequence
+ * child nodes from the visible nodes sequence.
*/
private void removeVisibleNodes(BranchInfo parentBranchInfo, int index, int count) {
parentBranchInfo.loadChildren();
@@ -1020,10 +1209,10 @@
rangeEnd++);
visibleNodes.remove(rangeStart, rangeEnd - rangeStart);
+
+ invalidateComponent();
}
}
-
- invalidateComponent();
}
/**
@@ -1048,6 +1237,16 @@
}
}
+ /**
+ * Clears our <tt>NodeInfo</tt> hierarchy of the specified cached field.
+ *
+ * @param mask
+ * The bitmask specifying which field to clear.
+ */
+ private void clearFields(byte mask) {
+ // TODO
+ }
+
@Override
public boolean mouseMove(Component component, int x, int y) {
boolean consumed = super.mouseMove(component, x, y);
@@ -1056,7 +1255,7 @@
if (showHighlight
&& treeView.getSelectMode() != TreeView.SelectMode.NONE) {
- NodeInfo previousHighlightedNode = this.highlightedNode;
+ NodeInfo previousHighlightedNode = highlightedNode;
highlightedNode = getNodeInfoAt(y);
if (highlightedNode != previousHighlightedNode) {
@@ -1086,59 +1285,67 @@
public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
boolean consumed = super.mouseDown(component, button, x, y);
- if (button == Mouse.Button.LEFT) {
+ if (!consumed
+ && button == Mouse.Button.LEFT) {
TreeView treeView = (TreeView)getComponent();
treeView.requestFocus();
NodeInfo nodeInfo = getNodeInfoAt(y);
if (nodeInfo != null
- && !nodeInfo.disabled) {
- boolean handled = false;
-
- Sequence<Integer> path = nodeInfo.getPath();
-
- // See if the user clicked on an expand/collapse control of a
- // branch. If so, expand/collapse the branch
- if (showBranchControls
- && nodeInfo instanceof BranchInfo) {
- BranchInfo branchInfo = (BranchInfo)nodeInfo;
-
- int nodeX = (branchInfo.depth - 1) * (indent + spacing);
+ && !nodeInfo.isDisabled()) {
+ int nodeHeight = getNodeHeight();
+ int baseNodeX = (nodeInfo.depth - 1) * (indent + spacing);
+
+ int nodeX = baseNodeX + (showBranchControls ? indent + spacing : 0);
+ int nodeY = (y / nodeHeight) * nodeHeight;
+
+ int checkboxWidth = CHECKBOX.getWidth();
+ int checkboxHeight = CHECKBOX.getHeight();
+
+ int checkboxX = Math.max(indent - checkboxWidth, 0) / 2;
+ int checkboxY = (nodeHeight - checkboxHeight) / 2;
+
+ // Only proceed if the user DIDN'T click on a checkbox
+ if (!treeView.getCheckmarksEnabled()
+ || x < nodeX + checkboxX
+ || x >= nodeX + checkboxX + checkboxWidth
+ || y < nodeY + checkboxY
+ || y >= nodeY + checkboxY + checkboxHeight) {
+ Sequence<Integer> path = nodeInfo.getPath();
+
+ // See if the user clicked on an expand/collapse control of
+ // a branch. If so, expand/collapse the branch
+ if (showBranchControls
+ && nodeInfo instanceof BranchInfo
+ && x >= baseNodeX
+ && x < baseNodeX + indent) {
+ BranchInfo branchInfo = (BranchInfo)nodeInfo;
- if (x >= nodeX
- && x < nodeX + indent) {
- treeView.setBranchExpanded(path, !branchInfo.expanded);
- handled = true;
+ treeView.setBranchExpanded(path, !branchInfo.isExpanded());
+ consumed = true;
}
- }
-
- // See if the user clicked on a checkbox. If so, update the
- // check state of the node
- if (!handled
- && treeView.getCheckmarksEnabled()) {
- // TODO Update node check state
- }
- // If we haven't handled the event, then proceed to manage the
- // selection state of the node
- if (!handled) {
- TreeView.SelectMode selectMode = treeView.getSelectMode();
-
- if (selectMode == TreeView.SelectMode.SINGLE) {
- if (!treeView.isNodeSelected(path)) {
- treeView.setSelectedPath(path);
- }
- } else if (selectMode == TreeView.SelectMode.MULTI) {
- if (Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
- if (treeView.isNodeSelected(path)) {
- treeView.removeSelectedPath(path);
+ // If we haven't consumed the event, then proceed to manage
+ // the selection state of the node
+ if (!consumed) {
+ TreeView.SelectMode selectMode = treeView.getSelectMode();
+
+ if (selectMode == TreeView.SelectMode.SINGLE) {
+ if (!treeView.isNodeSelected(path)) {
+ treeView.setSelectedPath(path);
+ }
+ } else if (selectMode == TreeView.SelectMode.MULTI) {
+ if (Keyboard.isPressed(Keyboard.Modifier.CTRL)) {
+ if (treeView.isNodeSelected(path)) {
+ treeView.removeSelectedPath(path);
+ } else {
+ treeView.addSelectedPath(path);
+ }
} else {
- treeView.addSelectedPath(path);
+ // Replace the selection
+ treeView.setSelectedPath(path);
}
- } else {
- // Replace the selection
- treeView.setSelectedPath(path);
}
}
}
@@ -1149,6 +1356,44 @@
}
@Override
+ public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
+ boolean consumed = super.mouseClick(component, button, x, y, count);
+
+ if (!consumed
+ && button == Mouse.Button.LEFT) {
+ TreeView treeView = (TreeView)getComponent();
+
+ NodeInfo nodeInfo = getNodeInfoAt(y);
+
+ if (nodeInfo != null
+ && !nodeInfo.isDisabled()) {
+ int nodeHeight = getNodeHeight();
+ int baseNodeX = (nodeInfo.depth - 1) * (indent + spacing);
+
+ int nodeX = baseNodeX + (showBranchControls ? indent + spacing : 0);
+ int nodeY = (y / nodeHeight) * nodeHeight;
+
+ int checkboxWidth = CHECKBOX.getWidth();
+ int checkboxHeight = CHECKBOX.getHeight();
+
+ int checkboxX = Math.max(indent - checkboxWidth, 0) / 2;
+ int checkboxY = (nodeHeight - checkboxHeight) / 2;
+
+ if (treeView.getCheckmarksEnabled()
+ && x >= nodeX + checkboxX
+ && x < nodeX + checkboxX + checkboxWidth
+ && y >= nodeY + checkboxY
+ && y < nodeY + checkboxY + checkboxHeight) {
+ Sequence<Integer> path = nodeInfo.getPath();
+ treeView.setNodeChecked(path, !treeView.isNodeChecked(path));
+ }
+ }
+ }
+
+ return consumed;
+ }
+
+ @Override
public boolean mouseWheel(Component component, Mouse.ScrollType scrollType, int scrollAmount,
int wheelRotation, int x, int y) {
boolean consumed = super.mouseWheel(component, scrollType, scrollAmount,
@@ -1184,7 +1429,7 @@
do {
newSelectedNode = (--index >= 0) ? visibleNodes.get(index) : null;
} while (newSelectedNode != null
- && newSelectedNode.disabled);
+ && newSelectedNode.isDisabled());
if (newSelectedNode != null) {
treeView.setSelectedPath(newSelectedNode.getPath());
@@ -1214,7 +1459,7 @@
do {
newSelectedNode = (++index <= n - 1) ? visibleNodes.get(index) : null;
} while (newSelectedNode != null
- && newSelectedNode.disabled);
+ && newSelectedNode.isDisabled());
if (newSelectedNode != null) {
treeView.setSelectedPath(newSelectedNode.getPath());
@@ -1237,7 +1482,7 @@
if (nodeInfo instanceof BranchInfo) {
BranchInfo branchInfo = (BranchInfo)nodeInfo;
- if (branchInfo.expanded) {
+ if (branchInfo.isExpanded()) {
treeView.collapseBranch(branchInfo.getPath());
}
}
@@ -1260,7 +1505,7 @@
if (nodeInfo instanceof BranchInfo) {
BranchInfo branchInfo = (BranchInfo)nodeInfo;
- if (!branchInfo.expanded) {
+ if (!branchInfo.isExpanded()) {
treeView.expandBranch(branchInfo.getPath());
}
}
@@ -1323,7 +1568,7 @@
}
if (treeView.getCheckmarksEnabled()) {
- nodeIndent += indent + spacing;
+ nodeIndent += Math.max(CHECKBOX.getWidth(), indent) + spacing;
}
return nodeIndent;
@@ -1353,16 +1598,21 @@
public void selectModeChanged(TreeView treeView,
TreeView.SelectMode previousSelectMode) {
- // No-op
+ // The selection has implicitly been cleared
+ clearFields(NodeInfo.SELECTED_MASK);
}
public void checkmarksEnabledChanged(TreeView treeView) {
+ // The check state of all nodes has implicitly been cleared
+ clearFields(NodeInfo.CHECK_STATE_MASK);
+
invalidateComponent();
}
public void showMixedCheckmarkStateChanged(TreeView treeView) {
if (treeView.getCheckmarksEnabled()) {
- // TODO update internal data model?
+ // TODO update check state of all NodeInfo structures
+
repaintComponent();
}
}
@@ -1372,14 +1622,14 @@
public void branchExpanded(TreeView treeView, Sequence<Integer> path) {
BranchInfo branchInfo = (BranchInfo)getNodeInfoAt(path);
- branchInfo.expanded = true;
+ branchInfo.setExpanded(true);
addVisibleNodes(branchInfo);
}
public void branchCollapsed(TreeView treeView, Sequence<Integer> path) {
BranchInfo branchInfo = (BranchInfo)getNodeInfoAt(path);
- branchInfo.expanded = false;
+ branchInfo.setExpanded(false);
removeVisibleNodes(branchInfo, 0, -1);
}
@@ -1464,13 +1714,18 @@
public void nodeDisabledChanged(TreeView treeView, Sequence<Integer> path) {
NodeInfo nodeInfo = getNodeInfoAt(path);
- nodeInfo.disabled = treeView.isNodeDisabled(path);
+ nodeInfo.setDisabled(treeView.isNodeDisabled(path));
+
repaintNode(nodeInfo);
}
public void nodeCheckStateChanged(TreeView treeView, Sequence<Integer> path,
TreeView.NodeCheckState previousCheckState) {
- // TODO
+ NodeInfo nodeInfo = getNodeInfoAt(path);
+
+ nodeInfo.setCheckState(treeView.getNodeCheckState(path));
+
+ repaintNode(nodeInfo);
}
// TreeViewSelectionListener methods
@@ -1478,14 +1733,14 @@
public void selectedPathAdded(TreeView treeView, Sequence<Integer> path) {
NodeInfo nodeInfo = getNodeInfoAt(path);
- nodeInfo.selected = true;
+ nodeInfo.setSelected(true);
repaintNode(nodeInfo);
}
public void selectedPathRemoved(TreeView treeView, Sequence<Integer> path) {
NodeInfo nodeInfo = getNodeInfoAt(path);
- nodeInfo.selected = false;
+ nodeInfo.setSelected(false);
repaintNode(nodeInfo);
}
@@ -1496,7 +1751,7 @@
for (int i = 0, n = previousSelectedPaths.getLength(); i < n; i++) {
NodeInfo previousSelectedNode = getNodeInfoAt(previousSelectedPaths.get(i));
- previousSelectedNode.selected = false;
+ previousSelectedNode.setSelected(false);
repaintNode(previousSelectedNode);
}
@@ -1506,7 +1761,7 @@
for (int i = 0, n = selectedPaths.getLength(); i < n; i++) {
NodeInfo selectedNode = getNodeInfoAt(selectedPaths.get(i));
- selectedNode.selected = true;
+ selectedNode.setSelected(true);
repaintNode(selectedNode);
}
}