package com.kartoflane.superluminal2.mvc.views;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import com.kartoflane.superluminal2.components.Polygon;
import com.kartoflane.superluminal2.core.Cache;
import com.kartoflane.superluminal2.ui.ShipContainer;
import com.kartoflane.superluminal2.utils.Utils;
public class RoomView extends BaseView {
public static final int RESIZE_HANDLE_LENGTH = 19;
public static final RGB WALL_RGB = new RGB(0, 0, 0);
public static final RGB FLOOR_RGB = new RGB(230, 225, 220);
private Color gridColor = null;
private Color handleColor = null;
private Polygon[] resizeHandles = null;
public RoomView() {
super();
gridColor = Cache.checkOutColor(this, CellView.GRID_RGB);
handleColor = Cache.checkOutColor(this, HIGHLIGHT_RGB);
setBorderColor(WALL_RGB);
setDefaultBorderColor(WALL_RGB);
setBackgroundColor(FLOOR_RGB);
setDefaultBackgroundColor(FLOOR_RGB);
setBorderThickness(2);
resizeHandles = new Polygon[4];
Point[] points = new Point[] { new Point(0, 0), new Point(0, 0), new Point(0, 0) };
points[1].x += RESIZE_HANDLE_LENGTH;
points[2].y += RESIZE_HANDLE_LENGTH;
resizeHandles[0] = new Polygon(points);
resizeHandles[1] = new Polygon(points);
resizeHandles[2] = new Polygon(points);
resizeHandles[3] = new Polygon(points);
resizeHandles[1].rotate((float) (Math.PI / 2), 0, 0);
resizeHandles[2].rotate((float) (Math.PI / 2) * 3, 0, 0);
resizeHandles[3].rotate((float) Math.PI, 0, 0);
}
/**
* Visibility for the controller, to allow to check whether a triangle was clicked.
*
* @return array of length 4, containing triangles representing the resize handles for the room.
*/
public Polygon[] getResizeHandles() {
return resizeHandles;
}
@Override
public void paintControl(PaintEvent e) {
if (alpha > 0) {
paintBackgroundSquare(e, backgroundColor, alpha);
// draw fake grid lines inside of rooms
if (controller.getW() > ShipContainer.CELL_SIZE || controller.getH() > ShipContainer.CELL_SIZE) {
Color prevFgColor = e.gc.getForeground();
e.gc.setForeground(gridColor);
paintFakeGridLines(e);
e.gc.setForeground(prevFgColor);
}
paintBorderSquare(e, borderColor, borderThickness, alpha);
if (controller.isSelected() && !controller.isPinned())
paintResizeHandles(e, handleColor, alpha / 2);
}
}
private void paintFakeGridLines(PaintEvent e) {
if (controller.getW() > ShipContainer.CELL_SIZE)
for (int i = 1; i < controller.getW() / ShipContainer.CELL_SIZE; i++)
e.gc.drawLine(controller.getX() - controller.getW() / 2 + i * ShipContainer.CELL_SIZE,
controller.getY() - controller.getH() / 2 + borderThickness,
controller.getX() - controller.getW() / 2 + i * ShipContainer.CELL_SIZE,
controller.getY() + controller.getH() / 2 - borderThickness);
if (controller.getH() > ShipContainer.CELL_SIZE)
for (int i = 1; i < controller.getH() / ShipContainer.CELL_SIZE; i++)
e.gc.drawLine(controller.getX() - controller.getW() / 2 + borderThickness,
controller.getY() - controller.getH() / 2 + i * ShipContainer.CELL_SIZE,
controller.getX() + controller.getW() / 2 - borderThickness,
controller.getY() - controller.getH() / 2 + i * ShipContainer.CELL_SIZE);
}
private void paintResizeHandles(PaintEvent e, Color color, int alpha) {
int prevAlpha = e.gc.getAlpha();
Color prevColor = e.gc.getBackground();
e.gc.setAlpha(alpha);
e.gc.setBackground(color);
for (int i = 0; i < 4; i++)
resizeHandles[i].fill(e);
e.gc.setAlpha(prevAlpha);
e.gc.setBackground(prevColor);
}
@Override
public void dispose() {
super.dispose();
Cache.checkInColor(this, CellView.GRID_RGB);
Cache.checkInColor(this, HIGHLIGHT_RGB);
handleColor = null;
gridColor = null;
}
@Override
public void updateView() {
if (controller.isSelected()) {
setBorderColor(controller.isPinned() ? PIN_RGB : SELECT_RGB);
setBackgroundColor(Utils.tint(defaultBackground, borderColor.getRGB(), 0.33));
setBorderThickness(2);
} else if (controller.isHighlighted()) {
setBorderColor(HIGHLIGHT_RGB);
setBackgroundColor(defaultBackground);
setBorderThickness(3);
} else {
setBorderColor(defaultBorder);
setBackgroundColor(defaultBackground);
setBorderThickness(2);
}
updateResizeHandles();
}
private void updateResizeHandles() {
Rectangle bounds = controller.getBounds();
// redefine triangles for resize handles
// top left corner
int x = bounds.x + 1;
int y = bounds.y + 1;
resizeHandles[0].setLocation(x + RESIZE_HANDLE_LENGTH / 2, y + RESIZE_HANDLE_LENGTH / 2);
// top right corner
x = bounds.x + controller.getW() + borderThickness - 1;
resizeHandles[1].setLocation(x - RESIZE_HANDLE_LENGTH / 2, y + RESIZE_HANDLE_LENGTH / 2);
// bottom right corner
y = bounds.y + controller.getH() + borderThickness - 1;
resizeHandles[3].setLocation(x - RESIZE_HANDLE_LENGTH / 2, y - RESIZE_HANDLE_LENGTH / 2);
// Yes, this is supposed to stay out of order -- this way we can access the triangle
// on the opposite corner via resizeHandles[3 - id]
// bottom left corner
x = bounds.x + 2;
resizeHandles[2].setLocation(x + RESIZE_HANDLE_LENGTH / 2, y - RESIZE_HANDLE_LENGTH / 2);
}
}