📄 form.java
字号:
if (numOfItems == 0 || traverseIndex < 0) { return; } i = items[traverseIndex]; } // SYNC NOTE: this call may result in a call to the // application, so we make sure we do this outside of the // LCDUILock i.callKeyReleased(keyCode); } /** * Handle a key repeat * * @param keyCode the key code of the key which was repeated */ void callKeyRepeated(int keyCode) { if (keyCode == Display.KEYCODE_UP || keyCode == Display.KEYCODE_DOWN || keyCode == Display.KEYCODE_LEFT || keyCode == Display.KEYCODE_RIGHT) { traverse(Display.getGameAction(keyCode)); } } /** * Handle a typed key from a keyboard * * @param c The char typed from the keyboard */ void callKeyTyped(char c) { Item i = null; synchronized (Display.LCDUILock) { if (numOfItems == 0 || traverseIndex < 0) { return; } i = items[traverseIndex]; } // SYNC NOTE: this call may result in a call to the // application, so we make sure we do this outside of the // LCDUILock i.callKeyTyped(c); } /** * Handle a pointer pressed event * * @param x The x coordinate of the press * @param y The y coordinate of the press */ void callPointerPressed(int x, int y) { Item i = null; synchronized (Display.LCDUILock) { if (numOfItems == 0 || traverseIndex < 0) { return; } i = items[traverseIndex]; x = (x - viewport[X] + view[X]) - i.bounds[X]; y = (y - viewport[Y] + view[Y]) - i.bounds[Y]; if (x < 0 || x > i.bounds[WIDTH] || y < 0 || y > i.bounds[HEIGHT]) { return; } pointerPressed = true; } // SYNC NOTE: this call may result in a call to the // application, so we make sure we do this outside of the // LCDUILock i.callPointerPressed(x, y); } /** * Handle a pointer released event * * @param x The x coordinate of the release * @param y The y coordinate of the release */ void callPointerReleased(int x, int y) { Item i = null; synchronized (Display.LCDUILock) { if (numOfItems == 0 || traverseIndex < 0 || !pointerPressed) { return; } i = items[traverseIndex]; x = (x - viewport[X] + view[X]) - i.bounds[X]; y = (y - viewport[Y] + view[Y]) - i.bounds[Y]; pointerPressed = false; } // SYNC NOTE: this call may result in a call to the // application, so we make sure we do this outside of the // LCDUILock i.callPointerReleased(x, y); } /** * Handle a pointer dragged event * * @param x The x coordinate of the drag * @param y The y coordinate of the drag */ void callPointerDragged(int x, int y) { Item i = null; synchronized (Display.LCDUILock) { if (numOfItems == 0 || traverseIndex < 0 || !pointerPressed) { return; } i = items[traverseIndex]; x = (x - viewport[X] + view[X]) - i.bounds[X]; y = (y - viewport[Y] + view[Y]) - i.bounds[Y]; } // SYNC NOTE: this call may result in a call to the // application, so we make sure we do this outside of the // LCDUILock i.callPointerDragged(x, y); } /** * The generic traverse method. This method determines the * current "mode" of traversal and delegates the traverse * to the appropriate handler, either formTraverse(), * itemTraverse() * * @param dir the direction of "traversal" */ void traverse(int dir) { // SYNC NOTE: formMode can only ever change as a result of a // traverse, which means its single-threaded (on the event thread) switch (formMode) { case FORM_TRAVERSE: try { formTraverse(dir); } catch (Throwable t) { // Swallow the error and move on } break; case ITEM_TRAVERSE: try { if (!itemTraverse(dir)) { formTraverse(dir); } } catch (Throwable t) { // Swallow the error and move on } break; } } /** * Traverse this Form in the given direction * * @param dir the direction of traversal */ void formTraverse(int dir) { // SYNC NOTE: rather than copy datasets all the time, we simply // protect ourselves from unexpected errors using a try/catch in // the traverse() method itself. The only problem that could occur // would be if the application added or removed Items on the fly // while the user was traversing. This could lead to an error // condition, but it would be rectified immediately by the // pending validation caused by the append/delete. This seems // preferable to wasting a lot of heap or employing complicating // locking behavior if (numOfItems == 0) { return; } // if that is the initial traverse in the form, // do it first if (dir == CustomItem.NONE) { setTraverseIndex(dir, traverseIndex, traverseIndex == -1 ? 0 : traverseIndex); return; } // If we need to scroll to fit the current item, // don't do a traverse, just return if (traverseIndex >= 0 && !items[traverseIndex].shouldSkipTraverse() && scrollForBounds(dir, items[traverseIndex].bounds)) { validateVisibility = true; repaintContents(); return; } int bendDir = dir; // We know we must do a "traversal". We always // perform a "direction bend" to achieve our // desired traversal semantics if (dir == Canvas.DOWN) { bendDir = Canvas.RIGHT; } else if (dir == Canvas.UP) { bendDir = Canvas.LEFT; } // Find new traverseIndex int oldIndex, newIndex = traverseIndex; do { oldIndex = newIndex; // Traverse to the next Item on the Form in the // given direction switch (bendDir) { case Canvas.UP: int ni1 = findNearestNeighborUp(); if (ni1 != -1) { newIndex = ni1; } break; case Canvas.DOWN: int ni2 = findNearestNeighborDown(); if (ni2 != -1) { newIndex = ni2; } break; case Canvas.LEFT: if (newIndex > 0) { newIndex--; } break; case Canvas.RIGHT: if (newIndex < (numOfItems - 1)) { newIndex++; } break; } // If we can't traverse any further in the given // direction, return if (oldIndex == newIndex) { return; } } while (items[newIndex].shouldSkipTraverse()); setTraverseIndex(dir, traverseIndex, newIndex); } /** * Sets traverseIndex on this Form * * @param dir the direction of traversal * @param oldIndex the old traverseIndex * @param newIndex the new traverseIndex to be set */ void setTraverseIndex(int dir, int oldIndex, int newIndex) { // SYNC NOTE: rather than copy datasets all the time, we simply // protect ourselves from unexpected errors using a try/catch in // the traverse() method itself. The only problem that could occur // would be if the application added or removed Items on the fly // while the user was traversing. This could lead to an error // condition, but it would be rectified immediately by the // pending validation caused by the append/delete. This seems // preferable to wasting a lot of heap or employing complicating // locking behavior if (dir == CustomItem.NONE) { // Make sure that initial traverseIndex is // not pointing to an item that is not traversable int newTraveseIndex = newIndex; // find first item with index from traverseIndex till // numOfItems-1 that is traversable boolean allSkipped = false; while (!allSkipped && items[newIndex].shouldSkipTraverse()) { newIndex++; if (newIndex == numOfItems) { allSkipped = true; } } // if all items with index from traverseIndex till numOfItems-1 // were skipped, we need to check if any of the items with index // from traverseIndex-1 till 0 that is traversable if (allSkipped) { if (newTraveseIndex > 0) { newIndex = newTraveseIndex - 1; while (items[newIndex].shouldSkipTraverse()) { newIndex--; if (newIndex == -1) { return; } } } else { return; } } } formMode = FORM_TRAVERSE; traverseIndex = newIndex; if (oldIndex >= 0 && oldIndex < numOfItems) { items[oldIndex].callTraverseOut(); } // setTraverseIndex is called from setCurrentItem. // It is possible that there was no layout done all. // In that case just return and layout will be done // when this form is first shown if (items[traverseIndex].bounds == null) { return; } if (dir == CustomItem.NONE) { dir = newIndex >= oldIndex ? Canvas.DOWN : Canvas.UP; } // If the newly traversed-to Item is outside the // viewport, we change our mode to FORM_SCROLL // so that subsequent 'traverses' will scroll the viewport // and bring the Item into view scrollForTraversal(dir, items[traverseIndex].bounds); itemTraverse(dir); validateVisibility = true; repaintContents(); updateCommandSet(); // FIX ME: improve the painting, a full repaintContents() should not // always be necessary } /** * Perform an internal traverse on the currently traversed-to * Item in the given direction. * * @param dir the direction of traversal * @return true if this item performed internal traversal */ boolean itemTraverse(int dir) { // SYNC NOTE: rather than copy datasets all the time, we simply
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -