X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fttree%2FTTreeViewWidget.java;fp=src%2Fjexer%2FTTreeView.java;h=adb9a5d8e354b1974d70843e608944e0dd4b5c8b;hb=d36057dfab8def933a64be042b039d76708ac5ba;hp=b9b05bf0fd492dc0d5b83933a0736d52d7720c55;hpb=eb29bbb5ec70c43895dd0f053630c7e3cd402cba;p=fanfix.git diff --git a/src/jexer/TTreeView.java b/src/jexer/ttree/TTreeViewWidget.java similarity index 58% rename from src/jexer/TTreeView.java rename to src/jexer/ttree/TTreeViewWidget.java index b9b05bf..adb9a5d 100644 --- a/src/jexer/TTreeView.java +++ b/src/jexer/ttree/TTreeViewWidget.java @@ -26,49 +26,31 @@ * @author Kevin Lamonte [kevin.lamonte@gmail.com] * @version 1 */ -package jexer; - +package jexer.ttree; + +import jexer.TAction; +import jexer.THScroller; +import jexer.TKeypress; +import jexer.TScrollableWidget; +import jexer.TVScroller; +import jexer.TWidget; import jexer.event.TKeypressEvent; import jexer.event.TMouseEvent; import static jexer.TKeypress.*; /** - * TTreeView implements a simple tree view. + * TTreeViewWidget wraps a tree view with horizontal and vertical scrollbars. */ -public class TTreeView extends TScrollableWidget { - - /** - * Root of the tree. - */ - private TTreeItem treeRoot; - - /** - * Get the root of the tree. - * - * @return the root of the tree - */ - public final TTreeItem getTreeRoot() { - return treeRoot; - } - - /** - * Set the root of the tree. - * - * @param treeRoot the new root of the tree - */ - public final void setTreeRoot(final TTreeItem treeRoot) { - this.treeRoot = treeRoot; - } +public class TTreeViewWidget extends TScrollableWidget { - /** - * Maximum width of a single line. - */ - private int maxLineWidth; + // ------------------------------------------------------------------------ + // Variables -------------------------------------------------------------- + // ------------------------------------------------------------------------ /** - * Only one of my children can be selected. + * The TTreeView */ - private TTreeItem selectedItem = null; + private TTreeView treeView; /** * If true, move the window to put the selected item in view. This @@ -77,22 +59,13 @@ public class TTreeView extends TScrollableWidget { private boolean centerWindow = false; /** - * The action to perform when the user selects an item. - */ - private TAction action = null; - - /** - * Set treeRoot. - * - * @param treeRoot ultimate root of tree - * @param centerWindow if true, move the window to put the root in view + * Maximum width of a single line. */ - public void setTreeRoot(final TTreeItem treeRoot, - final boolean centerWindow) { + private int maxLineWidth; - this.treeRoot = treeRoot; - this.centerWindow = centerWindow; - } + // ------------------------------------------------------------------------ + // Constructors ----------------------------------------------------------- + // ------------------------------------------------------------------------ /** * Public constructor. @@ -103,7 +76,7 @@ public class TTreeView extends TScrollableWidget { * @param width width of tree view * @param height height of tree view */ - public TTreeView(final TWidget parent, final int x, final int y, + public TTreeViewWidget(final TWidget parent, final int x, final int y, final int width, final int height) { this(parent, x, y, width, height, null); @@ -119,174 +92,22 @@ public class TTreeView extends TScrollableWidget { * @param height height of tree view * @param action action to perform when an item is selected */ - public TTreeView(final TWidget parent, final int x, final int y, + public TTreeViewWidget(final TWidget parent, final int x, final int y, final int width, final int height, final TAction action) { super(parent, x, y, width, height); - this.action = action; + + treeView = new TTreeView(this, 0, 0, getWidth() - 1, getHeight() - 1, + action); vScroller = new TVScroller(this, getWidth() - 1, 0, getHeight() - 1); hScroller = new THScroller(this, 0, getHeight() - 1, getWidth() - 1); - } - - /** - * Get the tree view item that was selected. - * - * @return the selected item, or null if no item is selected - */ - public final TTreeItem getSelected() { - return selectedItem; - } - - /** - * Set the new selected tree view item. - * - * @param item new item that became selected - */ - public void setSelected(final TTreeItem item) { - if (item != null) { - item.setSelected(true); - } - if ((selectedItem != null) && (selectedItem != item)) { - selectedItem.setSelected(false); - } - selectedItem = item; - } - - /** - * Perform user selection action. - */ - public void dispatch() { - if (action != null) { - action.DO(); - } - } - /** - * Resize text and scrollbars for a new width/height. - */ - @Override - public void reflowData() { - int selectedRow = 0; - boolean foundSelectedRow = false; - - if (treeRoot == null) { - return; - } - - // Make each child invisible/inactive to start, expandTree() will - // reactivate the visible ones. - for (TWidget widget: getChildren()) { - if (widget instanceof TTreeItem) { - TTreeItem item = (TTreeItem) widget; - item.setInvisible(true); - item.setEnabled(false); - item.keyboardPrevious = null; - item.keyboardNext = null; - } - } - - // Expand the tree into a linear list - getChildren().clear(); - getChildren().addAll(treeRoot.expandTree("", true)); - - // Locate the selected row and maximum line width - for (TWidget widget: getChildren()) { - TTreeItem item = (TTreeItem) widget; - - if (item == selectedItem) { - foundSelectedRow = true; - } - if (!foundSelectedRow) { - selectedRow++; - } - - int lineWidth = item.getText().length() - + item.getPrefix().length() + 4; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } - - if ((centerWindow) && (foundSelectedRow)) { - if ((selectedRow < getVerticalValue()) - || (selectedRow > getVerticalValue() + getHeight() - 2) - ) { - setVerticalValue(selectedRow); - centerWindow = false; - } - } - updatePositions(); - - // Rescale the scroll bars - setBottomValue(getChildren().size() - getHeight() + 1); - if (getBottomValue() < 0) { - setBottomValue(0); - } - if (getVerticalValue() > getBottomValue()) { - setVerticalValue(getBottomValue()); - } - setRightValue(maxLineWidth - getWidth() + 3); - if (getRightValue() < 0) { - setRightValue(0); - } - if (getHorizontalValue() > getRightValue()) { - setHorizontalValue(getRightValue()); - } - getChildren().add(hScroller); - getChildren().add(vScroller); } - /** - * Update the Y positions of all the children items. - */ - private void updatePositions() { - if (treeRoot == null) { - return; - } - - int begin = getVerticalValue(); - int topY = 0; - - // As we walk the list we also adjust next/previous pointers, - // resulting in a doubly-linked list but only of the expanded items. - TTreeItem p = null; - - for (int i = 0; i < getChildren().size(); i++) { - if (!(getChildren().get(i) instanceof TTreeItem)) { - // Skip the scrollbars - continue; - } - TTreeItem item = (TTreeItem) getChildren().get(i); - - if (p != null) { - item.keyboardPrevious = p; - p.keyboardNext = item; - } - p = item; - - if (i < begin) { - // Render invisible - item.setEnabled(false); - item.setInvisible(true); - continue; - } - - if (topY >= getHeight() - 1) { - // Render invisible - item.setEnabled(false); - item.setInvisible(true); - continue; - } - - item.setY(topY); - item.setEnabled(true); - item.setInvisible(false); - item.setWidth(getWidth() - 1); - topY++; - } - - } + // ------------------------------------------------------------------------ + // Event handlers --------------------------------------------------------- + // ------------------------------------------------------------------------ /** * Handle mouse press events. @@ -300,11 +121,13 @@ public class TTreeView extends TScrollableWidget { } else if (mouse.isMouseWheelDown()) { verticalIncrement(); } else { - // Pass to children + // Pass to the TreeView or scrollbars super.onMouseDown(mouse); } - // Update the screen after the scrollbars have moved + // Update the view to reflect the new scrollbar positions + treeView.setTopLine(getVerticalValue()); + treeView.setLeftColumn(getHorizontalValue()); reflowData(); } @@ -315,10 +138,28 @@ public class TTreeView extends TScrollableWidget { */ @Override public void onMouseUp(final TMouseEvent mouse) { - // Pass to children - super.onMouseDown(mouse); + // Pass to the TreeView or scrollbars + super.onMouseUp(mouse); + + // Update the view to reflect the new scrollbar positions + treeView.setTopLine(getVerticalValue()); + treeView.setLeftColumn(getHorizontalValue()); + reflowData(); + } + + /** + * Handle mouse motion events. + * + * @param mouse mouse motion event + */ + @Override + public void onMouseMotion(final TMouseEvent mouse) { + // Pass to the TreeView or scrollbars + super.onMouseMotion(mouse); - // Update the screen after any thing has expanded/contracted + // Update the view to reflect the new scrollbar positions + treeView.setTopLine(getVerticalValue()); + treeView.setLeftColumn(getHorizontalValue()); reflowData(); } @@ -359,36 +200,29 @@ public class TTreeView extends TScrollableWidget { || keypress.equals(kbAltPgDn) ) { bigVerticalIncrement(); - } else if (keypress.equals(kbHome)) { - toTop(); - } else if (keypress.equals(kbEnd)) { - toBottom(); - } else if (keypress.equals(kbEnter)) { - if (selectedItem != null) { - dispatch(); + } else if (keypress.equals(kbPgDn)) { + for (int i = 0; i < getHeight() - 2; i++) { + treeView.onKeypress(new TKeypressEvent(TKeypress.kbDown)); } - } else if (keypress.equals(kbUp)) { - // Select the previous item - if (selectedItem != null) { - TTreeItem oldItem = selectedItem; - if (selectedItem.keyboardPrevious != null) { - setSelected(selectedItem.keyboardPrevious); - if (oldItem.getY() == 0) { - verticalDecrement(); - } - } - } - } else if (keypress.equals(kbDown)) { - // Select the next item - if (selectedItem != null) { - TTreeItem oldItem = selectedItem; - if (selectedItem.keyboardNext != null) { - setSelected(selectedItem.keyboardNext); - if (oldItem.getY() == getHeight() - 2) { - verticalIncrement(); - } - } + reflowData(); + return; + } else if (keypress.equals(kbPgUp)) { + for (int i = 0; i < getHeight() - 2; i++) { + treeView.onKeypress(new TKeypressEvent(TKeypress.kbUp)); } + reflowData(); + return; + } else if (keypress.equals(kbHome)) { + treeView.setSelected((TTreeItem) treeView.getChildren().get(0), + false); + treeView.setTopLine(0); + reflowData(); + return; + } else if (keypress.equals(kbEnd)) { + treeView.setSelected((TTreeItem) treeView.getChildren().get( + treeView.getChildren().size() - 1), true); + reflowData(); + return; } else if (keypress.equals(kbTab)) { getParent().switchWidget(true); return; @@ -396,17 +230,157 @@ public class TTreeView extends TScrollableWidget { || keypress.equals(kbBackTab)) { getParent().switchWidget(false); return; - } else if (selectedItem != null) { - // Give the TTreeItem a chance to handle arrow keys - selectedItem.onKeypress(keypress); } else { - // Pass other keys (tab etc.) on to TWidget's handler. - super.onKeypress(keypress); + treeView.onKeypress(keypress); + + // Update the scrollbars to reflect the new data position + reflowData(); return; } - // Update the screen after any thing has expanded/contracted + // Update the view to reflect the new scrollbar position + treeView.setTopLine(getVerticalValue()); + treeView.setLeftColumn(getHorizontalValue()); reflowData(); } + // ------------------------------------------------------------------------ + // TScrollableWidget ------------------------------------------------------ + // ------------------------------------------------------------------------ + + /** + * Resize text and scrollbars for a new width/height. + */ + @Override + public void reflowData() { + int selectedRow = 0; + boolean foundSelectedRow = false; + + // Reset the keyboard list, expandTree() will recreate it. + for (TWidget widget: treeView.getChildren()) { + TTreeItem item = (TTreeItem) widget; + item.keyboardPrevious = null; + item.keyboardNext = null; + } + + // Expand the tree into a linear list + treeView.getChildren().clear(); + treeView.getChildren().addAll(treeView.getTreeRoot().expandTree("", + true)); + + // Locate the selected row and maximum line width + for (TWidget widget: treeView.getChildren()) { + TTreeItem item = (TTreeItem) widget; + + if (item == treeView.getSelected()) { + foundSelectedRow = true; + } + if (!foundSelectedRow) { + selectedRow++; + } + + int lineWidth = item.getText().length() + + item.getPrefix().length() + 4; + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + + if ((centerWindow) && (foundSelectedRow)) { + if ((selectedRow < getVerticalValue()) + || (selectedRow > getVerticalValue() + getHeight() - 2) + ) { + treeView.setTopLine(selectedRow); + centerWindow = false; + } + } + treeView.alignTree(); + + // Rescale the scroll bars + setVerticalValue(treeView.getTopLine()); + setBottomValue(treeView.getTotalLineCount() - (getHeight() - 1)); + if (getBottomValue() < getTopValue()) { + setBottomValue(getTopValue()); + } + if (getVerticalValue() > getBottomValue()) { + setVerticalValue(getBottomValue()); + } + setRightValue(maxLineWidth - 2); + if (getHorizontalValue() > getRightValue()) { + setHorizontalValue(getRightValue()); + } + + } + + // ------------------------------------------------------------------------ + // TTreeView -------------------------------------------------------------- + // ------------------------------------------------------------------------ + + /** + * Get the underlying TTreeView. + * + * @return the TTreeView + */ + public TTreeView getTreeView() { + return treeView; + } + + /** + * Get the root of the tree. + * + * @return the root of the tree + */ + public final TTreeItem getTreeRoot() { + return treeView.getTreeRoot(); + } + + /** + * Set the root of the tree. + * + * @param treeRoot the new root of the tree + */ + public final void setTreeRoot(final TTreeItem treeRoot) { + treeView.setTreeRoot(treeRoot); + } + + /** + * Set treeRoot. + * + * @param treeRoot ultimate root of tree + * @param centerWindow if true, move the window to put the root in view + */ + public void setTreeRoot(final TTreeItem treeRoot, + final boolean centerWindow) { + + treeView.setTreeRoot(treeRoot); + this.centerWindow = centerWindow; + } + + /** + * Get the tree view item that was selected. + * + * @return the selected item, or null if no item is selected + */ + public final TTreeItem getSelected() { + return treeView.getSelected(); + } + + /** + * Set the new selected tree view item. + * + * @param item new item that became selected + * @param centerWindow if true, move the window to put the selected into + * view + */ + public void setSelected(final TTreeItem item, final boolean centerWindow) { + treeView.setSelected(item, centerWindow); + } + + /** + * Perform user selection action. + */ + public void dispatch() { + treeView.dispatch(); + } + }