📄 gauge.java
字号:
* Return the minimum height for this gauge * * @return the minimum height */ int callMinimumHeight() { return callPreferredHeight(-1); } /** * Get the preferred height for this gauge for the given width * * @param w the width to compute the height for * @return the height preferred for the given width */ int callPreferredHeight(int w) { if (maxValue == INDEFINITE) { return INCREMENTAL_SPRITE.getHeight() + getLabelHeight(w); } else { // NTS: Don't know why the '+2' is needed return GAUGE_HEIGHT + getLabelHeight(w) + 2; } } /** * Handle traversal within this Gauge * * @param dir the direction of traversal * @param viewportWidth the width of the viewport * @param viewportHeight the height of the viewport * @param visRect the in/out rectangle for the internal traversal location * @return True if traversal occurred within this Gauge */ boolean callTraverse(int dir, int viewportWidth, int viewportHeight, int[] visRect) { super.callTraverse(dir, viewportWidth, viewportHeight, visRect); if (!traversedIn) { traversedIn = true; return true; } else if (interactive) { switch (dir) { case Canvas.LEFT: case Canvas.RIGHT: modifyValue(dir); return true; case Canvas.UP: case Canvas.DOWN: return false; } } return false; } /** * Traverse out of this Gauge */ void callTraverseOut() { super.callTraverseOut(); traversedIn = false; } /** * Paint the contents of this gauge * * @param g the graphics to paint to * @param w the width of this gauge * @param h the height of this gauge */ void callPaint(Graphics g, int w, int h) { if (blockCount == -1) { setBlockCountAndValue(w); } int clipX = g.getClipX(); // We need to check the clip to determine if // the label needs painting int labelHeight = super.paintLabel(g, w); g.translate(0, labelHeight); if (maxValue == INDEFINITE) { spriteInUse.paint(g); } else { int RGBdrawColor; if (hasFocus) { RGBdrawColor = Display.FG_COLOR; } else { g.setColor(0x00606060); // dark gray // Keep in mind that on a 1-bit display, dark gray will // round to black RGBdrawColor = 0x00606060; } // setup the scroll arrows. setGaugeArrows(); // paint left arrow if necessary. if (interactive) { // check clip boundaries. if (clipX < blockMargin) { if (drawLeftArrow) { g.drawImage(LEFTARROW_IMG, // (BLOCK_SPACE / 2) + (arrowWidth / 2), 2, GAUGE_HEIGHT / 2, Graphics.LEFT | Graphics.VCENTER); } else { g.setColor(Display.ERASE_COLOR); g.fillRect(0, // BLOCK_SPACE / 2, 2, arrowWidth, GAUGE_HEIGHT); g.setColor(RGBdrawColor); } } } // Depending on the clip, we may need to repaint // only some or all of the blocks. int startBlock = blockCount; int stopBlock = blockCount; if (clipX - blockMargin < (blockCount * BLOCK_SPACE)) { startBlock = (clipX - blockMargin) / BLOCK_SPACE; // we don't want a startBlock < 0 // (which happens if the clip is off to the left) startBlock = startBlock < 0 ? 0 : startBlock; // only when we have calculated a startBlock // do we want to calculate a stopBlock if (clipX + g.getClipWidth() > blockMargin) { stopBlock = (clipX + g.getClipWidth() - blockMargin) / BLOCK_SPACE; stopBlock ++; // increment so that we take care of // a clip x-coord in the middle // of a block // we don't want a startBlock < 0 // (which happens if the clip is off to the left) stopBlock = stopBlock > blockCount ? blockCount : stopBlock; } } // these values are used in calculating the blockHeight // they only need to be calculated once every paint int bc = blockCount - 1; int bc2 = bc * bc; for (int i = startBlock; i < stopBlock; i++) { int blockHeight = GAUGE_HEIGHT; if (interactive && blockCount > 1) { // // this implements a quadratic spline from // p0 to p2 using p1 as a control point to // affect the curve // // int p0 = 5, // minimum height // p1 = 1, // control point // p2 = GAUGE_HEIGHT - p0; // maximum height // // the original equation is below, but the one used // has been expanded to use the p values above // // blockHeight = p0 + // (2 * p1 * i * (bc - i) / bc2) + // ((p2 * (i * i)) / bc2); // blockHeight = 5 + (((i * (bc - i)) << 1) / bc2) + (((GAUGE_HEIGHT - 5) * (i * i)) / bc2); } if ((valueOfEachBlock * (i + 1)) > value && value != maxValue) { if (hasFocus) { g.drawRect(blockMargin + (i * BLOCK_SPACE), GAUGE_HEIGHT - blockHeight, BLOCK_SPACE - 3, blockHeight); } else { g.setStrokeStyle(Graphics.DOTTED); g.drawRect(blockMargin + (i * BLOCK_SPACE), GAUGE_HEIGHT - blockHeight, BLOCK_SPACE - 3, blockHeight); g.setStrokeStyle(Graphics.SOLID); } } else { // // + 1 on the width and height so that // the blocks look the size if they are // empty or filled // g.fillRect(blockMargin + (i * BLOCK_SPACE), GAUGE_HEIGHT - blockHeight, BLOCK_SPACE - 3 + 1, blockHeight + 1); } } if (interactive) { if (drawRightArrow == true) { g.drawImage(RIGHTARROW_IMG, blockMargin + ((blockCount)*BLOCK_SPACE) + (arrowWidth / 2), GAUGE_HEIGHT / 2, Graphics.HCENTER | Graphics.VCENTER); } else { g.setColor(Display.ERASE_COLOR); g.fillRect(blockMargin + ((blockCount)*BLOCK_SPACE) + (arrowWidth / 2), 0, arrowWidth, GAUGE_HEIGHT); g.setColor(RGBdrawColor); } } if (!hasFocus) { g.setColor(Display.FG_COLOR); } } // max value != INDEFINITE g.translate(0, -labelHeight); } /** * Possibly handle a value change * * @param dir the direction key the user pressed to change * the value */ void modifyValue(int dir) { Form form = null; synchronized (Display.LCDUILock) { // There are two cases where we need to repaint a // block when a user changes a Gauge's value: // 1. If the user is increasing the Gauge's value // and the value increases such that a new bar // needs to be filled in. The easy test for this // is: value % valueOfEachBlock == 0, indicating // the value has increased precisely enough to // fill in an entire block. // // 2. If the user is decreasing the Gauge's value // and the value decreases such that a currently // filled in bar needs to be un-filled. The easy // test for this is: // (value + 1) % valueOfEachBlock == 0, indicating // we have just decreased 1 unit below a full // block. int blockToRepaint = -1; int oldValue = value; if (dir == Canvas.LEFT) { if (value % valueOfEachBlock == 0) { blockToRepaint = (value / valueOfEachBlock) - 1; } else if (value == maxValue) { blockToRepaint = blockCount - 1; } value--; } else { value++; if (value % valueOfEachBlock == 0) { blockToRepaint = (value / valueOfEachBlock) - 1; } else if (value == maxValue) { blockToRepaint = blockCount - 1; } } checkValue(); // Because of the necessity to call repaintImpl() // in case of boundary conditions also, // we always call repaintImpl() // Avoids artefacts caused by not refreshing the arrows. // We need to remember to offset by the height of our // label if there is one. int blockY = getLabelHeight(bounds[WIDTH]); // Cause a repaintImpl // of the blocks if (blockToRepaint < blockCount) { repaint(blockMargin + (blockToRepaint * BLOCK_SPACE), blockY, BLOCK_SPACE, GAUGE_HEIGHT + 2); } // of the left arrow if (blockToRepaint <= 0) { repaint(2, blockY, arrowWidth, GAUGE_HEIGHT); } // of the right arrow if (blockToRepaint >= blockCount - 1) { repaint(blockMargin + (blockCount * BLOCK_SPACE), blockY, arrowWidth, GAUGE_HEIGHT); } if (value != oldValue) { // notify the ItemStateChangedListener form = (Form)this.getOwner(); } } // end synchronized // SYNC NOTE: We make sure we notify the ItemStateChangedListener // outside of our lock if (form != null) { form.itemStateChanged(this); } } /** * Called by the system to notify this Item it is being shown * * <p>The default implementation of this method updates * the 'visible' state */ void callShowNotify() { if (maxValue == INDEFINITE && value == CONTINUOUS_RUNNING && updateHelper == null) { setValue(CONTINUOUS_RUNNING); } this.visible = true; } /** * Called by the system to notify this Item it is being hidden * * <p>The default implementation of this method updates * the 'visible' state */ void callHideNotify() { if (updateHelper != null) { cancelGaugeUpdateTask(); } this.visible = false; } // private implementation /** * In cases where this gauge is used in an INDEFINITE mode we * need these sprites around. */ private void initSprites() { INCREMENTAL_SPRITE = new Sprite(INCREMENTAL_IMG, 44, 45); CONTINUOUS_SPRITE = new Sprite(CONTINUOUS_IMG, 29, 33); } /** * Set the value of each block. This will use the * blockCount value and maxValue to assign a value
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -