diff options
Diffstat (limited to 'src/jrummikub/view/impl/StonePainter.java')
-rw-r--r-- | src/jrummikub/view/impl/StonePainter.java | 504 |
1 files changed, 252 insertions, 252 deletions
diff --git a/src/jrummikub/view/impl/StonePainter.java b/src/jrummikub/view/impl/StonePainter.java index b901e78..0700966 100644 --- a/src/jrummikub/view/impl/StonePainter.java +++ b/src/jrummikub/view/impl/StonePainter.java @@ -19,256 +19,256 @@ import jrummikub.model.StoneColor; * coordinates */ class StonePainter { - private static final float ASPECT_RATIO = 0.75f; - private static final float DEFAULT_WIDTH = 40; - private static final float TEXT_POS = 0.275f; - private static final float FACE_WIDTH = 0.475f; - private static final float CIRCLE_POS = 0.725f; - private static final float CIRCLE_WIDTH = 0.45f; - - private static final Color BACKGROUND_COLOR = new Color(0.9f, 0.9f, 0.6f); - private static final Color SELECTED_COLOR = BACKGROUND_COLOR.darker(); - - private static final float BRIGHTER_SCALE = 1.15f; - - /** - * The width of one pixel in the scale of 1.0 - */ - public static final float WIDTH_SCALE = 1 / DEFAULT_WIDTH; - /** - * The height of one pixel in the scale of 1.0 - */ - public static final float HEIGHT_SCALE = ASPECT_RATIO / DEFAULT_WIDTH; - - private float scale; - - private static int even(float f) { - return 2 * (int) (f / 2); - } - - private static Color brighter(Color color) { - int r = (int) (color.getRed() * BRIGHTER_SCALE); - int g = (int) (color.getRed() * BRIGHTER_SCALE); - int b = (int) (color.getRed() * BRIGHTER_SCALE); - - return new Color(r > 255 ? 255 : r, g > 255 ? 255 : g, b > 255 ? 255 : b); - } - - private static Color getColor(StoneColor color) { - switch (color) { - case BLACK: - return new Color(0.15f, 0.15f, 0.15f); - case BLUE: - return new Color(0.0f, 0.0f, 1.0f); - case ORANGE: - return new Color(1.0f, 0.6f, 0.0f); - case RED: - return new Color(0.9f, 0.0f, 0.25f); - } - - return null; - } - - /** - * Sets the new grid scale - * - * @param scale - * the new scale - */ - public void setScale(float scale) { - this.scale = scale; - } - - /** - * @return the current grid scale - */ - public float getScale() { - return scale; - } - - /** - * @param x - * x position in screen coordinates - * @param y - * y position in screen coordinates - * @return position in grid coordinates - */ - public Position calculatePosition(int x, int y) { - float width = getStoneWidth(); - float height = getStoneHeight(); - - return new Position(x / width, y / height); - } - - /** - * @return the width of a stone in the current scale in pixels - */ - public int getStoneWidth() { - return even(DEFAULT_WIDTH * scale); - } - - /** - * @return the height of a stone in the current scale in pixels - */ - public int getStoneHeight() { - return (int) (DEFAULT_WIDTH * scale / ASPECT_RATIO); - } - - /** - * @param scale - * the scaling factor for the grid coordinates - */ - StonePainter(float scale) { - this.scale = scale; - } - - private void paintStoneBackground(Graphics2D g, Rectangle r, Color background) { - // Paint background - g.setColor(background); - g.fillRect(r.x, r.y, r.width, r.height); - - // Paint bevel border - g.setColor(brighter(brighter(background))); - g.fillRect(r.x, r.y, 1, r.height); - g.setColor(brighter(background)); - g.fillRect(r.x + 1, r.y + 1, 1, r.height - 2); - - g.setColor(brighter(brighter(background))); - g.fillRect(r.x, r.y, r.width, 1); - g.setColor(brighter(background)); - g.fillRect(r.x + 1, r.y + 1, r.width - 2, 1); - - g.setColor(background.darker().darker()); - g.fillRect(r.x + r.width - 1, r.y, 1, r.height); - g.setColor(background.darker()); - g.fillRect(r.x + r.width - 2, r.y + 1, 1, r.height - 2); - - g.setColor(background.darker().darker()); - g.fillRect(r.x, r.y + r.height - 1, r.width, 1); - g.setColor(background.darker()); - g.fillRect(r.x + 1, r.y + r.height - 2, r.width - 2, 1); - } - - private void paintJokerFace(Graphics2D g, Rectangle r) { - Stroke oldStroke = g.getStroke(); - - g.setStroke(new BasicStroke(2)); - g.drawOval(r.x, r.y, r.width, r.height); - - g.setStroke(new BasicStroke(1)); - GeneralPath path = new GeneralPath(); - // nose - path.moveTo(r.x + 0.5f * r.width, r.y + 0.45f * r.height); - path.lineTo(r.x + 0.53f * r.width, r.y + 0.6f * r.height); - path.lineTo(r.x + 0.47f * r.width, r.y + 0.6f * r.height); - path.closePath(); - g.fill(path); - - path.reset(); - // mouth, left - path.moveTo(r.x + 0.23f * r.width, r.y + 0.75f * r.width); - path.lineTo(r.x + 0.27f * r.width, r.y + 0.65f * r.width); - // mouth, middle - path.moveTo(r.x + 0.25f * r.width, r.y + 0.7f * r.width); - path.lineTo(r.x + 0.5f * r.width, r.y + 0.8f * r.width); - path.lineTo(r.x + 0.75f * r.width, r.y + 0.7f * r.width); - // mouth, right - path.moveTo(r.x + 0.77f * r.width, r.y + 0.75f * r.width); - path.lineTo(r.x + 0.73f * r.width, r.y + 0.65f * r.width); - g.draw(path); - - path.reset(); - // left eye - path.moveTo(r.x + 0.3f * r.width, r.y + 0.41f * r.height); - path.lineTo(r.x + 0.375f * r.width, r.y + 0.375f * r.height); - path.lineTo(r.x + 0.3f * r.width, r.y + 0.34f * r.height); - path.lineTo(r.x + 0.225f * r.width, r.y + 0.375f * r.height); - path.closePath(); - g.draw(path); - - path.reset(); - // right eye - path.moveTo(r.x + 0.7f * r.width, r.y + 0.41f * r.height); - path.lineTo(r.x + 0.625f * r.width, r.y + 0.375f * r.height); - path.lineTo(r.x + 0.7f * r.width, r.y + 0.34f * r.height); - path.lineTo(r.x + 0.775f * r.width, r.y + 0.375f * r.height); - path.closePath(); - g.draw(path); - - g.setStroke(oldStroke); - } - - private void paintJoker(Graphics2D g, Rectangle r, Color color) { - int faceSize = even(FACE_WIDTH * r.width); - int pos = r.y + (int) (TEXT_POS * r.height); - - g.setColor(color); - paintJokerFace(g, new Rectangle(r.x + r.width / 2 - faceSize / 2, pos - - faceSize / 2, faceSize, faceSize)); - } - - private void paintStoneValue(Graphics2D g, Rectangle r, Color color, int v) { - int pos = r.y + (int) (TEXT_POS * r.height); - - g.setFont(new Font("SansSerif", Font.BOLD, r.height / 4)); - FontMetrics fm = g.getFontMetrics(); - String value = Integer.toString(v); - Rectangle2D stringRect = fm.getStringBounds(value, g); - - g.setColor(color.darker()); - g.drawString(value, - (int) (r.x + r.width / 2 - stringRect.getWidth() / 2) + 1, - pos + (fm.getAscent() - fm.getDescent()) / 2 + 1); - g.setColor(color); - g.drawString(value, (int) (r.x + r.width / 2 - stringRect.getWidth() / 2), - pos + (fm.getAscent() - fm.getDescent()) / 2); - } - - private void paintCircle(Graphics2D g, Rectangle r, Color background) { - int size = even(r.width * CIRCLE_WIDTH); - int pos = r.y + (int) (CIRCLE_POS * r.height); - - // Paint circle - g.setColor(background.darker()); - g.drawArc(r.x + r.width / 2 - size / 2, pos - size / 2, size, size, 50, 170); - - g.setColor(brighter(background)); - g.drawArc((int) (r.x + r.width / 2 - size / 2), pos - size / 2, size, size, - -130, 170); - } - - /** - * Paints a stone - * - * @param g - * the graphics context to paint the stone on - * @param stone - * the stone to paint - * @param p - * the position of the stone - * @param selected - * if selected is true the stone will be painted darker - */ - public void paintStone(Graphics2D g, Stone stone, Position p, boolean selected) { - Color background = selected ? SELECTED_COLOR : BACKGROUND_COLOR; - int width = getStoneWidth(); - int height = getStoneHeight(); - - Rectangle rect = new Rectangle((int) (p.getX() * width), - (int) (p.getY() * height), width, height); - - paintStoneBackground(g, rect, background); - - Color color = getColor(stone.getColor()); - if (selected) - color = color.darker(); - - if (stone.isJoker()) { - paintJoker(g, rect, color); - } else { - paintStoneValue(g, rect, color, stone.getValue()); - } - - paintCircle(g, rect, background); - } + private static final float ASPECT_RATIO = 0.75f; + private static final float DEFAULT_WIDTH = 40; + private static final float TEXT_POS = 0.275f; + private static final float FACE_WIDTH = 0.475f; + private static final float CIRCLE_POS = 0.725f; + private static final float CIRCLE_WIDTH = 0.45f; + + private static final Color BACKGROUND_COLOR = new Color(0.9f, 0.9f, 0.6f); + private static final Color SELECTED_COLOR = BACKGROUND_COLOR.darker(); + + private static final float BRIGHTER_SCALE = 1.15f; + + /** + * The width of one pixel in the scale of 1.0 + */ + public static final float WIDTH_SCALE = 1 / DEFAULT_WIDTH; + /** + * The height of one pixel in the scale of 1.0 + */ + public static final float HEIGHT_SCALE = ASPECT_RATIO / DEFAULT_WIDTH; + + private float scale; + + private static int even(float f) { + return 2 * (int) (f / 2); + } + + private static Color brighter(Color color) { + int r = (int) (color.getRed() * BRIGHTER_SCALE); + int g = (int) (color.getRed() * BRIGHTER_SCALE); + int b = (int) (color.getRed() * BRIGHTER_SCALE); + + return new Color(r > 255 ? 255 : r, g > 255 ? 255 : g, b > 255 ? 255 : b); + } + + private static Color getColor(StoneColor color) { + switch (color) { + case BLACK: + return new Color(0.15f, 0.15f, 0.15f); + case BLUE: + return new Color(0.0f, 0.0f, 1.0f); + case ORANGE: + return new Color(1.0f, 0.6f, 0.0f); + case RED: + return new Color(0.9f, 0.0f, 0.25f); + } + + return null; + } + + /** + * Sets the new grid scale + * + * @param scale + * the new scale + */ + public void setScale(float scale) { + this.scale = scale; + } + + /** + * @return the current grid scale + */ + public float getScale() { + return scale; + } + + /** + * @param x + * x position in screen coordinates + * @param y + * y position in screen coordinates + * @return position in grid coordinates + */ + public Position calculatePosition(int x, int y) { + float width = getStoneWidth(); + float height = getStoneHeight(); + + return new Position(x / width, y / height); + } + + /** + * @return the width of a stone in the current scale in pixels + */ + public int getStoneWidth() { + return even(DEFAULT_WIDTH * scale); + } + + /** + * @return the height of a stone in the current scale in pixels + */ + public int getStoneHeight() { + return (int) (DEFAULT_WIDTH * scale / ASPECT_RATIO); + } + + /** + * @param scale + * the scaling factor for the grid coordinates + */ + StonePainter(float scale) { + this.scale = scale; + } + + private void paintStoneBackground(Graphics2D g, Rectangle r, Color background) { + // Paint background + g.setColor(background); + g.fillRect(r.x, r.y, r.width, r.height); + + // Paint bevel border + g.setColor(brighter(brighter(background))); + g.fillRect(r.x, r.y, 1, r.height); + g.setColor(brighter(background)); + g.fillRect(r.x + 1, r.y + 1, 1, r.height - 2); + + g.setColor(brighter(brighter(background))); + g.fillRect(r.x, r.y, r.width, 1); + g.setColor(brighter(background)); + g.fillRect(r.x + 1, r.y + 1, r.width - 2, 1); + + g.setColor(background.darker().darker()); + g.fillRect(r.x + r.width - 1, r.y, 1, r.height); + g.setColor(background.darker()); + g.fillRect(r.x + r.width - 2, r.y + 1, 1, r.height - 2); + + g.setColor(background.darker().darker()); + g.fillRect(r.x, r.y + r.height - 1, r.width, 1); + g.setColor(background.darker()); + g.fillRect(r.x + 1, r.y + r.height - 2, r.width - 2, 1); + } + + private void paintJokerFace(Graphics2D g, Rectangle r) { + Stroke oldStroke = g.getStroke(); + + g.setStroke(new BasicStroke(2)); + g.drawOval(r.x, r.y, r.width, r.height); + + g.setStroke(new BasicStroke(1)); + GeneralPath path = new GeneralPath(); + // nose + path.moveTo(r.x + 0.5f * r.width, r.y + 0.45f * r.height); + path.lineTo(r.x + 0.53f * r.width, r.y + 0.6f * r.height); + path.lineTo(r.x + 0.47f * r.width, r.y + 0.6f * r.height); + path.closePath(); + g.fill(path); + + path.reset(); + // mouth, left + path.moveTo(r.x + 0.23f * r.width, r.y + 0.75f * r.width); + path.lineTo(r.x + 0.27f * r.width, r.y + 0.65f * r.width); + // mouth, middle + path.moveTo(r.x + 0.25f * r.width, r.y + 0.7f * r.width); + path.lineTo(r.x + 0.5f * r.width, r.y + 0.8f * r.width); + path.lineTo(r.x + 0.75f * r.width, r.y + 0.7f * r.width); + // mouth, right + path.moveTo(r.x + 0.77f * r.width, r.y + 0.75f * r.width); + path.lineTo(r.x + 0.73f * r.width, r.y + 0.65f * r.width); + g.draw(path); + + path.reset(); + // left eye + path.moveTo(r.x + 0.3f * r.width, r.y + 0.41f * r.height); + path.lineTo(r.x + 0.375f * r.width, r.y + 0.375f * r.height); + path.lineTo(r.x + 0.3f * r.width, r.y + 0.34f * r.height); + path.lineTo(r.x + 0.225f * r.width, r.y + 0.375f * r.height); + path.closePath(); + g.draw(path); + + path.reset(); + // right eye + path.moveTo(r.x + 0.7f * r.width, r.y + 0.41f * r.height); + path.lineTo(r.x + 0.625f * r.width, r.y + 0.375f * r.height); + path.lineTo(r.x + 0.7f * r.width, r.y + 0.34f * r.height); + path.lineTo(r.x + 0.775f * r.width, r.y + 0.375f * r.height); + path.closePath(); + g.draw(path); + + g.setStroke(oldStroke); + } + + private void paintJoker(Graphics2D g, Rectangle r, Color color) { + int faceSize = even(FACE_WIDTH * r.width); + int pos = r.y + (int) (TEXT_POS * r.height); + + g.setColor(color); + paintJokerFace(g, new Rectangle(r.x + r.width / 2 - faceSize / 2, pos + - faceSize / 2, faceSize, faceSize)); + } + + private void paintStoneValue(Graphics2D g, Rectangle r, Color color, int v) { + int pos = r.y + (int) (TEXT_POS * r.height); + + g.setFont(new Font("SansSerif", Font.BOLD, r.height / 4)); + FontMetrics fm = g.getFontMetrics(); + String value = Integer.toString(v); + Rectangle2D stringRect = fm.getStringBounds(value, g); + + g.setColor(color.darker()); + g.drawString(value, + (int) (r.x + r.width / 2 - stringRect.getWidth() / 2) + 1, + pos + (fm.getAscent() - fm.getDescent()) / 2 + 1); + g.setColor(color); + g.drawString(value, (int) (r.x + r.width / 2 - stringRect.getWidth() / 2), + pos + (fm.getAscent() - fm.getDescent()) / 2); + } + + private void paintCircle(Graphics2D g, Rectangle r, Color background) { + int size = even(r.width * CIRCLE_WIDTH); + int pos = r.y + (int) (CIRCLE_POS * r.height); + + // Paint circle + g.setColor(background.darker()); + g.drawArc(r.x + r.width / 2 - size / 2, pos - size / 2, size, size, 50, 170); + + g.setColor(brighter(background)); + g.drawArc((int) (r.x + r.width / 2 - size / 2), pos - size / 2, size, size, + -130, 170); + } + + /** + * Paints a stone + * + * @param g + * the graphics context to paint the stone on + * @param stone + * the stone to paint + * @param p + * the position of the stone + * @param selected + * if selected is true the stone will be painted darker + */ + public void paintStone(Graphics2D g, Stone stone, Position p, boolean selected) { + Color background = selected ? SELECTED_COLOR : BACKGROUND_COLOR; + int width = getStoneWidth(); + int height = getStoneHeight(); + + Rectangle rect = new Rectangle((int) (p.getX() * width), + (int) (p.getY() * height), width, height); + + paintStoneBackground(g, rect, background); + + Color color = getColor(stone.getColor()); + if (selected) + color = color.darker(); + + if (stone.isJoker()) { + paintJoker(g, rect, color); + } else { + paintStoneValue(g, rect, color, stone.getValue()); + } + + paintCircle(g, rect, background); + } } |