Improved list navigation

up/shift+tab: select previous item
down/tab: select next item
enter: insert item below selection
shift+enter: insert item above selection
This commit is contained in:
Nathan Dinsmore 2014-05-26 18:51:17 -04:00
parent b858d029dc
commit 093d725039
2 changed files with 36 additions and 21 deletions

View file

@ -30,10 +30,10 @@ public class ListCell extends Sprite {
public var tf:TextField;
private var frame:ResizeableFrame;
public function ListCell(s:String, width:int, whenChanged:Function, nextCell:Function) {
public function ListCell(s:String, width:int, whenChanged:Function, keyPress:Function) {
frame = new ResizeableFrame(0xFFFFFF, Specs.listColor, 6, true);
addChild(frame);
addTextField(whenChanged, nextCell);
addTextField(whenChanged, keyPress);
tf.text = s;
setWidth(width);
}
@ -54,7 +54,7 @@ public class ListCell extends Sprite {
frame.setWidthHeight(tf.width, frameH);
}
private function addTextField(whenChanged:Function, nextCell:Function):void {
private function addTextField(whenChanged:Function, keyPress:Function):void {
tf = new TextField();
tf.type = 'input';
tf.wordWrap = true;
@ -63,13 +63,13 @@ public class ListCell extends Sprite {
tf.x = 3;
tf.y = 1;
tf.addEventListener(Event.CHANGE, whenChanged);
tf.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, nextCell);
tf.addEventListener(KeyboardEvent.KEY_DOWN, keyPress);
addChild(tf);
}
public function select():void {
stage.focus = tf;
tf.setSelection(0, tf.getLineLength(0));
tf.setSelection(0, tf.text.length);
}
}}

View file

@ -309,13 +309,14 @@ public class ListWatcher extends Sprite {
// Add Item Button Support
//------------------------------
private function addItem(b:IconButton):void {
private function addItem(b:IconButton = null):void {
// Called when addItemButton is clicked.
if ((root is Scratch) && !(root as Scratch).editMode) return;
if (insertionIndex < 0) insertionIndex = contents.length;
contents.splice(insertionIndex, 0, '***');
contents.splice(insertionIndex, 0, '');
updateContents();
updateScrollbar();
selectCell(insertionIndex);
}
private function gotFocus(e:FocusEvent):void {
@ -327,7 +328,7 @@ public class ListWatcher extends Sprite {
insertionIndex = -1;
for (var i:int = 0; i < visibleCells.length; i++) {
if (visibleCells[i] == newFocus.parent) {
insertionIndex = firstVisibleIndex + i;
insertionIndex = firstVisibleIndex + i + 1;
return;
}
}
@ -462,7 +463,7 @@ public class ListWatcher extends Sprite {
private function allocateCell(s:String, width:int):ListCell {
// Allocate a ListCell with the given contents and width.
// Recycle one from the cell pool if possible.
if (cellPool.length == 0) return new ListCell(s, width, textChanged, nextCell);
if (cellPool.length == 0) return new ListCell(s, width, textChanged, keyPress);
var result:ListCell = cellPool.pop();
result.setText(s, width);
return result;
@ -515,23 +516,37 @@ public class ListWatcher extends Sprite {
}
}
private function nextCell(e:Event):void {
// Triggered by tab key. Select the next cell in the list.
private function selectCell(i:int, scroll:Boolean = true):void {
var j:int = i - firstVisibleIndex;
if (j >= 0 && j < visibleCells.length) {
visibleCells[j].select();
insertionIndex = i + 1;
} else if (scroll) {
scrollToIndex(i);
selectCell(i, false);
}
}
private function keyPress(e:KeyboardEvent):void {
// Respond to a key press on a cell.
if (e.keyCode == 13) {
if (e.shiftKey) insertionIndex--;
addItem();
return;
}
if (contents.length < 2) return; // only one cell, and it's already selected
var direction:int =
e.keyCode == 38 ? -1 :
e.keyCode == 40 ? 1 :
e.keyCode == 9 ? (e.shiftKey ? -1 : 1) : 0;
if (direction == 0) return;
var cellContents:TextField = e.target as TextField;
for (var i:int = 0; i < visibleCells.length; i++) {
var cell:ListCell = visibleCells[i];
if (cell.tf == cellContents) {
e.preventDefault();
if (contents.length < 2) return; // only one cell, and it's already selected
if (i + 1 < visibleCells.length) {
visibleCells[i + 1].select();
return;
} else {
var selectIndex:int = (firstVisibleIndex + i + 1) % contents.length;
scrollToIndex(selectIndex);
var j:int = firstVisibleIndex - selectIndex;
if (j >= 0 && j < visibleCells.length) visibleCells[j].select();
}
selectCell((firstVisibleIndex + i + direction + contents.length) % contents.length);
return;
}
}
}