/* * Copyright © 2011 Nokia Corporation. All rights reserved. * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. * Oracle and Java are trademarks or registered trademarks of Oracle and/or its * affiliates. Other product and company names mentioned herein may be trademarks * or trade names of their respective owners. * See LICENSE.TXT for license information. */ package com.nokia.example.moviebooking.ui; import com.nokia.example.moviebooking.moviedb.Showing; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; 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.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Shell; /** * Contains the seat distribution and facilities to select it */ class SeatingCanvas extends Canvas implements PaintListener, ControlListener, KeyListener, MouseListener { private Showing showing; private int[][] selected; private Image doubleBuffer; private GC gc; private boolean[][] seats; private int seatCount; private int selectedRow, firstSelectedSeat; private int rows; private int seatsPerRow; private Shell shell; private Point seatSize; private Rectangle screenRectangle; SeatingCanvas(Shell shell, Showing showing, int[][] selectedSeating, int seatCount) { super(shell, SWT.NO_BACKGROUND); this.showing = showing; this.shell = shell; this.seatCount = seatCount; this.selected = selectedSeating; seats = showing.getSeating(); rows = seats.length; seatsPerRow = seats[0].length; init(); } void init() { // Select the first free seats selected = new int[seatCount][2]; for (int i = 0; i < rows; i++) { if (searchSeatsInRow(i, 0)) { selectedRow = i; break; } } // This is necessary to repaint the screen addPaintListener(this); // Request to listen for keys addKeyListener(this); //Listen for touch events addMouseListener(this); // Listen if the size of the parent changes shell.addControlListener(this); } public void keyPressed(KeyEvent e) { // Nothing to do, we are only interested in key releases } public void keyReleased(KeyEvent e) { // Check if the arrow keys are pressed if (e.keyCode == SWT.ARROW_UP) { if (selectedRow > 0) { searchSeatsInRow(selectedRow - 1, firstSelectedSeat); redraw(); } } else if (e.keyCode == SWT.ARROW_DOWN) { if (selectedRow < (rows - 1)) { searchSeatsInRow(selectedRow + 1, firstSelectedSeat); redraw(); } } else if (e.keyCode == SWT.ARROW_LEFT) { if (firstSelectedSeat > 0) { searchSeatsInRow(selectedRow, firstSelectedSeat - 1); redraw(); } } else if (e.keyCode == SWT.ARROW_RIGHT) { if (firstSelectedSeat < (seatsPerRow - seatCount)) { searchSeatsInRow(selectedRow, firstSelectedSeat + 1); redraw(); } } } public void paintControl(PaintEvent e) { // Dump the offscreen image onto the canvas drawSeating(); e.gc.drawImage(doubleBuffer, 0, 0); } public void controlMoved(ControlEvent e) { // We are not interested in this event } public void controlResized(ControlEvent e) { // Recreate the double buffer with the new size if (doubleBuffer != null) { doubleBuffer.dispose(); } doubleBuffer = null; if (gc != null) { gc.dispose(); } gc = null; redraw(); } // Returns the currently selected seats int[][] getSelectedSeats() { return selected; } public void destroy() { if (doubleBuffer != null) { doubleBuffer.dispose(); } if (gc != null) { gc.dispose(); } } // Search if seatCount seats are available in row i private boolean searchSeatsInRow(int i, int firstSelectedSeat) { int k = 0; for (int j = firstSelectedSeat; j < seatsPerRow; j++) { if (!seats[i][j]) { k++; } } if (k >= seatCount) { k = 0; for (int j = firstSelectedSeat; j < seatsPerRow && k < seatCount; j++) { if (!seats[i][j]) { selected[k][0] = i; selected[k++][1] = j; } } selectedRow = i; this.firstSelectedSeat = selected[0][1]; return true; } else { return false; } } // Drawing of the offscreen image private void drawSeating() { Color bgColor = getDisplay().getSystemColor(SWT.COLOR_WHITE); Color occupiedSeatColor = getDisplay().getSystemColor(SWT.COLOR_RED); Color availableSeatColor = getDisplay().getSystemColor(SWT.COLOR_BLUE); Color frameColor = getDisplay().getSystemColor(SWT.COLOR_BLACK); Color selectedSeatColor = getDisplay().getSystemColor(SWT.COLOR_GREEN); Color screenColor = getDisplay().getSystemColor(SWT.COLOR_GRAY); if (doubleBuffer == null) { doubleBuffer = new Image(getDisplay(), getBounds()); } if (gc == null) { gc = new GC(doubleBuffer); } Rectangle screen = getScreen(); // Clear the image /*Point canvasSize = new Point(shell.getClientArea().width, shell.getClientArea().height); */ Point canvasSize = getSize(); gc.setBackground(bgColor); gc.fillRectangle(0, 0, canvasSize.x, canvasSize.y); gc.setForeground(frameColor); gc.drawRectangle(1, 1, canvasSize.x - 2, canvasSize.y - 2); gc.setForeground(screenColor); gc.setBackground(screenColor); gc.fillRectangle(screen); boolean[][] seats = showing.getSeating(); int rows = seats.length; int seatsPerRow = seats[0].length; int radius = getRadius(rows, seatsPerRow); // Space per seat/row Point seatSize = getSeatSize(rows, seatsPerRow); // Empty space to leave for horizontal center alignment int xOffset = getOffsetX(screen, seatsPerRow, seatSize); for (int i = 0; i < rows; i++) { for (int j = 0; j < seatsPerRow; j++) { if (seats[i][j]) { gc.setBackground(occupiedSeatColor); } else { gc.setBackground(availableSeatColor); } gc.fillOval(screen.x + xOffset + j * seatSize.x, (screen.y + screen.height + radius / 2) + i * seatSize.y, radius, radius); } } for (int i = 0; i < selected.length; i++) { gc.setBackground(selectedSeatColor); System.out.println("selected[i][1]" + selected[i][1]); System.out.println("selected[i][0]" + selected[i][0]); gc.fillOval(screen.x + xOffset + selected[i][1] * seatSize.x, (screen.y + screen.height + radius / 2) + selected[i][0] * seatSize.y, radius, radius); } } private int getOffsetX(Rectangle screen, int seatsPerRow, Point seatSize) { int xOffset = (screen.width - seatSize.x * seatsPerRow) / 2; return xOffset; } private Rectangle getScreen() { Point canvasSize = getSize(); int width = (95 * canvasSize.x) / 100; int height = canvasSize.y / 20; screenRectangle = new Rectangle( (canvasSize.x - width) / 2, height, width, height); return screenRectangle; } /** * Calculate the seat per size/row * * @param canvasSize * @param screen * @param rows * @param seatsPerRow * @param radius * @return */ private Point getSeatSize(int rows, int seatsPerRow) { int radius = getRadius(rows, seatsPerRow); Rectangle screen = getScreen(); int spacex = screen.width / seatsPerRow; int spacey = ((getSize().y - (screen.height + screen.y + radius / 2)) / rows); seatSize = new Point(spacex, spacey); return seatSize; } private int getRadius(int rows, int seatsPerRow) { Rectangle screen = getScreen(); int radius = Math.min((screen.width / seatsPerRow), ((getSize().y - (screen.height + screen.y)) / rows)) - 2; return radius; } public void mouseDoubleClick(MouseEvent event) { // Nothing to do } public void mouseDown(MouseEvent event) { handleMouse(event); } public void mouseUp(MouseEvent event) { handleMouse(event); } private void handleMouse(MouseEvent event) { Rectangle screen = getScreen(); Point seatSize = getSeatSize(seats.length, seats[0].length); if (event.y > (screen.y + screen.height)) { int col = (event.x) / seatSize.x; if (col < 1) { col = 1; } if (col > seats[0].length) { col = seats[0].length; } int row = (event.y - screen.y) / seatSize.y; if (row < 1) { row = 1; } if (row > seats.length) { row = seats.length; } for (int seat = 0; seat < seatCount && col < seatsPerRow; col++) { if (!seats[row - 1][col - 1]) { selected[seat][0] = row - 1; selected[seat][1] = col - 1; seat++; } } redraw(); } } }