Package swtgui

Source Code of swtgui.SudokuCanvas

package swtgui;

import java.util.Arrays;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;

import sudoku.Sudoku;

/**
*
* @author Niels
* @version 0.1
*/
public class SudokuCanvas extends Canvas {
  private Color[][] colors = new Color[9][9];
  private boolean[][] dirty = new boolean[9][9];

  /**
   * An extension of a canvas for drawing sudokus.
   *
   * @param composite
   *            The parent composite.
   * @param style
   *            The style of the composite.
   */
  public SudokuCanvas(Composite composite, final GUI gui, int style) {
    super(composite, style | SWT.NO_BACKGROUND);

    // Fill with default values.
    for (int i = 0; i < 9; i++) {
      Arrays.fill(colors[i], GUI.BLACK);
      Arrays.fill(dirty[i], true);
    }

    // Add a paint listener
    addPaintListener(new PaintListener() {
      /*
       * (non-Javadoc)
       *
       * @see
       * org.eclipse.swt.events.PaintListener#paintControl(org.eclipse
       * .swt.events.PaintEvent)
       */
      @Override
      public void paintControl(PaintEvent e) {
        GC gc = e.gc;

        for (int i = 0; i < 9; i++)
          for (int k = 0; k < 9; k++)
            if (dirty[i][k]) {
              drawSquare(gc, getClientArea(), i, k,
                  gui.getSudoku(), colors[i][k]);
              dirty[i][k] = false;
            }
      }
    });

    // Add the mouse listener
    addMouseListener(new MouseListener() {
      /*
       * (non-Javadoc)
       *
       * @see
       * org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.
       * events.MouseEvent)
       */
      @Override
      public void mouseUp(MouseEvent e) {
      }

      /*
       * (non-Javadoc)
       *
       * @see
       * org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt
       * .events.MouseEvent)
       */
      @Override
      public void mouseDown(MouseEvent e) {
        if (gui.isSolving())
          return;
        Rectangle rectangle = getClientArea();
        int width = rectangle.width / 9;
        int height = rectangle.height / 9;
        int row = e.x / width;
        int column = e.y / height;

        new ChoiceDialog(GUI.shell, gui, row, column);
      }

      /*
       * (non-Javadoc)
       *
       * @see
       * org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse
       * .swt.events.MouseEvent)
       */
      @Override
      public void mouseDoubleClick(MouseEvent arg0) {
      }
    });

  }

  /**
   * Draws a complete sudoku on the given gc with the given rectangle as
   * drawing area.
   */
  public static void drawSudoku(GC gc, Rectangle rectangle, Sudoku sudoku) {
    for (int i = 0; i < 9; i++)
      for (int k = 0; k < 9; k++)
        drawSquare(gc, rectangle, i, k, sudoku,
            sudoku.isAssignment(i, k) ? GUI.BLUE : GUI.BLACK);
  }

  /**
   * Draws a square with a number on the given graphics context, with the
   * given rectangle as client area.
   *
   * @param gc
   *            The graphics context to draw upon.
   * @param rectangle
   *            The bounds of the drawing region.
   * @param row
   *            The row of the square.
   * @param column
   *            The column of the square.
   */
  public static void drawSquare(GC gc, Rectangle rectangle, int row,
      int column, Sudoku sudoku, Color color) {
    int width = rectangle.width / 9;
    int height = rectangle.height / 9;
    int thick = Math.max(1, width / 30);
    gc.setForeground(GUI.BLACK);
    gc.setBackground(GUI.WHITE);

    // Draw the background.
    gc.fillRectangle(rectangle.x + row * width, rectangle.y + column
        * height, width - 1, height - 1);

    // Adapt the font to the correct size.
    FontData data = GUI.FONT.getFontData()[0];
    data.setHeight(height / 2);
    Font font = new Font(GUI.display, data);
    gc.setFont(font);

    // Set the text to draw.
    String string = sudoku.getValueAt(row, column) == 0 ? " " : ""
        + sudoku.getValueAt(row, column);
    Point extent = gc.stringExtent(string);

    // Draw the text
    gc.setForeground(color);
    gc.drawText(string, rectangle.x + row * width + (width - extent.x) / 2,
        rectangle.y + column * height + (height - extent.y) / 2);
    // Cleanu
    font.dispose();

    gc.setBackground(GUI.BLACK);

    // Draw the horizontal lines.
    if (column == 0 || column == 3 || column == 6)
      gc.fillRectangle(rectangle.x + row * width, rectangle.y + column
          * height, width - 1, thick * 2);
    else if (column == 8)
      gc.fillRectangle(rectangle.x + row * width, rectangle.y + 9
          * height - thick * 2 - 1, width - 1, thick * 2);
    gc.fillRectangle(rectangle.x + row * width, rectangle.y + (column + 1)
        * height - thick / 2, width - 1, thick / 2);
    gc.fillRectangle(rectangle.x + row * width, rectangle.y + column
        * height, width - 1, thick / 2 + 1);

    // Draw the vertical lines
    if (row == 0 || row == 3 || row == 6)
      gc.fillRectangle(rectangle.x + row * width, rectangle.y + column
          * height, thick * 2, height - 1);
    else if (row == 8)
      gc.fillRectangle(rectangle.x + 9 * width - thick * 2 - 1,
          rectangle.y + column * height, thick * 2, height - 1);
    gc.fillRectangle(rectangle.x + row * width - thick / 2, rectangle.y
        + column * height, thick / 2, height);
    gc.fillRectangle(rectangle.x + row * width, rectangle.y + column
        * height, thick / 2 + 1, height);
  }

  /**
   * Sets the value of the given row and column.
   *
   * @param row
   *            The row of the value to set.
   * @param column
   *            The column of the value to set.
   * @param value
   *            The value to set.
   */
  public void setDirty(int row, int column) {
    if (isDisposed())
      return;
    Rectangle r = getBounds();
    int width = r.width / 9;
    int height = r.height / 9;
    dirty[row][column] = true;

    redraw(row * width, column * width, width, height, true);
  }

  /**
   * Sets the color of the given row and column.
   *
   * @param row
   *            The row of the value to set.
   * @param column
   *            The column of the value to set.
   * @param color
   *            The color to set.
   */
  public void setColor(int row, int column, Color color) {
    if (isDisposed())
      return;
    Rectangle r = getBounds();
    int width = r.width / 9;
    int height = r.height / 9;
    colors[row][column] = color;
    dirty[row][column] = true;
    redraw(row * width, column * width, width, height, true);
  }

  public void redraw() {
    for (int i = 0; i < 9; i++)
      Arrays.fill(dirty[i], true);
    super.redraw();
  }
}
TOP

Related Classes of swtgui.SudokuCanvas

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.