diff --git a/navalplanner-gantt-zk/src/main/java/org/zkoss/ganttz/TaskDetail.java b/navalplanner-gantt-zk/src/main/java/org/zkoss/ganttz/TaskDetail.java index 0dd1f0c95..ef83a10c2 100644 --- a/navalplanner-gantt-zk/src/main/java/org/zkoss/ganttz/TaskDetail.java +++ b/navalplanner-gantt-zk/src/main/java/org/zkoss/ganttz/TaskDetail.java @@ -4,6 +4,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.DateFormat; import java.util.Date; +import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -11,6 +12,7 @@ import org.zkoss.ganttz.util.TaskBean; import org.zkoss.util.Locales; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlMacroComponent; +import org.zkoss.zk.ui.event.KeyEvent; import org.zkoss.zk.ui.ext.AfterCompose; import org.zkoss.zul.Datebox; import org.zkoss.zul.Textbox; @@ -100,6 +102,86 @@ public class TaskDetail extends HtmlMacroComponent implements AfterCompose { dateBox.setOpen(true); } + private enum Navigation { + LEFT, UP, RIGHT, DOWN; + public static Navigation getIntentFrom(KeyEvent keyEvent) { + return values()[keyEvent.getKeyCode() - 37]; + } + } + + TaskDetail getAboveDetail() { + List parentChildren = getParent().getChildren(); + // TODO can be optimized + int positionInParent = parentChildren.indexOf(this); + if (positionInParent == 0) + return null; + return (TaskDetail) parentChildren.get(positionInParent - 1); + } + + TaskDetail getBelowDetail() { + List parentChildren = getParent().getChildren(); + int positionInParent = parentChildren.indexOf(this); + if (positionInParent == parentChildren.size() - 1) + return null; + return (TaskDetail) parentChildren.get(positionInParent + 1); + } + + private Textbox[] getTextBoxes() { + return new Textbox[] { nameBox, startDateTextBox, endDateTextBox }; + } + + public void focusGoUp(int position) { + TaskDetail aboveDetail = getAboveDetail(); + if (aboveDetail != null) { + aboveDetail.getTextBoxes()[position].focus(); + } + } + + public void focusGoDown(int position) { + TaskDetail belowDetail = getBelowDetail(); + if (belowDetail != null) { + belowDetail.getTextBoxes()[position].focus(); + } + } + + public void userWantsToMove(Textbox textbox, KeyEvent keyEvent) { + Navigation navigation = Navigation.getIntentFrom(keyEvent); + List textBoxSiblingsIncludedItself = getTextBoxSiblingsIncludedItself(textbox); + int position = textBoxSiblingsIncludedItself.indexOf(textbox); + switch (navigation) { + case UP: + focusGoUp(position); + break; + case DOWN: + focusGoDown(position); + break; + case LEFT: + if (position == 0) { + focusGoUp(getTextBoxes().length - 1); + } else { + textBoxSiblingsIncludedItself.get(position - 1).focus(); + } + break; + case RIGHT: + if (position < textBoxSiblingsIncludedItself.size() - 1) + textBoxSiblingsIncludedItself.get(position + 1).focus(); + else { + focusGoDown(0); + } + break; + default: + throw new RuntimeException("case not covered: " + navigation); + } + } + + private List getTextBoxSiblingsIncludedItself(Textbox textbox) { + Component parent = textbox.getParent(); + List children = parent.getChildren(); + List textboxes = Planner.findComponentsOfType(Textbox.class, + children); + return textboxes; + } + /** * When the dateBox loses focus the corresponding textbox is shown instead. * @param dateBox diff --git a/navalplanner-gantt-zk/src/main/resources/web/ganttz/zul/taskdetail.zul b/navalplanner-gantt-zk/src/main/resources/web/ganttz/zul/taskdetail.zul index f7ea36f65..130f8a4a4 100644 --- a/navalplanner-gantt-zk/src/main/resources/web/ganttz/zul/taskdetail.zul +++ b/navalplanner-gantt-zk/src/main/resources/web/ganttz/zul/taskdetail.zul @@ -4,10 +4,10 @@ ]]> - - + + - +