/**
* Copyright (C) 2010, LGPL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* @author Matfyz, fyzmat@gmail.com
*/
package mines.gui;
import mines.MinesUtils;
import com.trolltech.qt.core.Qt.MouseButton;
import com.trolltech.qt.gui.*;
import java.util.HashMap;
import java.util.Map;
import mines.GUI_FIELD;
import mines.MinefieldContainer.Coord;
/**
* Triangle button, which represents a field.
*/
public class MineButton extends QGraphicsPixmapItem{
/**
* Class, which loads the buttons bitmaps from the resources.
*/
private static class ResourceLoader {
/** Transparent color of the bitmap */
private static final QColor TRANSPARENT_COLOR = QColor.fromRgb(255, 0, 255);
/** Images of down oriented buttons */
private static Map<GUI_FIELD, QPixmap> mDownButtonImages = loadDownButtons();
/** Images of up oriented buttons */
private static Map<GUI_FIELD, QPixmap> mUpButtonImages = loadUpButtons();
/**
* Loads the image from specified resource.
* @param imageFilename Filename of the resource.
* @return The loaded image.
*/
private static QPixmap loadImageFromResources(String imageFilename) {
String fullPath = "classpath:resources/minebuttons/" + imageFilename;
QPixmap picture = new QPixmap(fullPath);
if (picture.isNull()) {
throw new Error("Unable to initialize image: " + imageFilename);
}
// make some parts of the image transparent.
QBitmap mask = picture.createMaskFromColor(TRANSPARENT_COLOR);
picture.setMask(mask);
return picture;
}
/**
* Loads all the down oriented buttons.
* @return Map of the buttons.
*/
private static Map<GUI_FIELD, QPixmap> loadDownButtons() {
Map<GUI_FIELD, QPixmap> result = new HashMap<GUI_FIELD, QPixmap>();
result.put(GUI_FIELD.ZERO, loadImageFromResources("minebutton_down_0.bmp"));
result.put(GUI_FIELD.ONE, loadImageFromResources("minebutton_down_1.bmp"));
result.put(GUI_FIELD.TWO, loadImageFromResources("minebutton_down_2.bmp"));
result.put(GUI_FIELD.THREE, loadImageFromResources("minebutton_down_3.bmp"));
result.put(GUI_FIELD.FOUR, loadImageFromResources("minebutton_down_4.bmp"));
result.put(GUI_FIELD.FIVE, loadImageFromResources("minebutton_down_5.bmp"));
result.put(GUI_FIELD.SIX, loadImageFromResources("minebutton_down_6.bmp"));
result.put(GUI_FIELD.SEVEN, loadImageFromResources("minebutton_down_7.bmp"));
result.put(GUI_FIELD.EIGHT, loadImageFromResources("minebutton_down_8.bmp"));
result.put(GUI_FIELD.NINE, loadImageFromResources("minebutton_down_9.bmp"));
result.put(GUI_FIELD.TEN, loadImageFromResources("minebutton_down_10.bmp"));
result.put(GUI_FIELD.ELEVEN, loadImageFromResources("minebutton_down_11.bmp"));
result.put(GUI_FIELD.TWELVE, loadImageFromResources("minebutton_down_12.bmp"));
result.put(GUI_FIELD.COVERED, loadImageFromResources("minebutton_down_covered.bmp"));
result.put(GUI_FIELD.MINE, loadImageFromResources("minebutton_down_mine.bmp"));
result.put(GUI_FIELD.FIRED_MINE, loadImageFromResources("minebutton_down_fired.bmp"));
result.put(GUI_FIELD.MARKED_MINE, loadImageFromResources("minebutton_down_marked_mine.bmp"));
result.put(GUI_FIELD.MARKED_CLEAR, loadImageFromResources("minebutton_down_marked_clear.bmp"));
result.put(GUI_FIELD.FLAG, loadImageFromResources("minebutton_down_flag.bmp"));
return result;
}
/**
* Loads the up oriented buttons.
* @return Map of the buttons.
*/
private static Map<GUI_FIELD, QPixmap> loadUpButtons() {
Map<GUI_FIELD, QPixmap> result = new HashMap<GUI_FIELD, QPixmap>();
result.put(GUI_FIELD.ZERO, loadImageFromResources("minebutton_up_0.bmp"));
result.put(GUI_FIELD.ONE, loadImageFromResources("minebutton_up_1.bmp"));
result.put(GUI_FIELD.TWO, loadImageFromResources("minebutton_up_2.bmp"));
result.put(GUI_FIELD.THREE, loadImageFromResources("minebutton_up_3.bmp"));
result.put(GUI_FIELD.FOUR, loadImageFromResources("minebutton_up_4.bmp"));
result.put(GUI_FIELD.FIVE, loadImageFromResources("minebutton_up_5.bmp"));
result.put(GUI_FIELD.SIX, loadImageFromResources("minebutton_up_6.bmp"));
result.put(GUI_FIELD.SEVEN, loadImageFromResources("minebutton_up_7.bmp"));
result.put(GUI_FIELD.EIGHT, loadImageFromResources("minebutton_up_8.bmp"));
result.put(GUI_FIELD.NINE, loadImageFromResources("minebutton_up_9.bmp"));
result.put(GUI_FIELD.TEN, loadImageFromResources("minebutton_up_10.bmp"));
result.put(GUI_FIELD.ELEVEN, loadImageFromResources("minebutton_up_11.bmp"));
result.put(GUI_FIELD.TWELVE, loadImageFromResources("minebutton_up_12.bmp"));
result.put(GUI_FIELD.COVERED, loadImageFromResources("minebutton_up_covered.bmp"));
result.put(GUI_FIELD.MINE, loadImageFromResources("minebutton_up_mine.bmp"));
result.put(GUI_FIELD.FIRED_MINE, loadImageFromResources("minebutton_up_fired.bmp"));
result.put(GUI_FIELD.MARKED_MINE, loadImageFromResources("minebutton_up_marked_mine.bmp"));
result.put(GUI_FIELD.MARKED_CLEAR, loadImageFromResources("minebutton_up_marked_clear.bmp"));
result.put(GUI_FIELD.FLAG, loadImageFromResources("minebutton_up_flag.bmp"));
return result;
}
/**
* Get the image of specified button.
* @param type Graphical view of the button.
* @param down Orientation of the button - true to down.
* @return The image of the button.
*/
public static QPixmap getMineButtonImage(GUI_FIELD type, boolean down) {
Map<GUI_FIELD, QPixmap> searchedMap = down ? mDownButtonImages : mUpButtonImages;
if(!searchedMap.containsKey(type)) {
throw new Error("Internal error, mine button image is missing" + type + " " + down);
}
return searchedMap.get(type);
}
}
/** Signal, when the user left clicks on this button */
public Signal1<Coord> mLeftButtonPressed = new Signal1<Coord>();
/** Signal, when the user right clicks on this button */
public Signal1<Coord> mRightButtonPressed = new Signal1<Coord>();
/** Signal, when the user moves the mouse cursor over this button */
public Signal1<Coord> mMouseMovedOver = new Signal1<Coord>();
/** Width in pixels of all the images of buttons*/
static final int BITMAP_WIDTH = 28;
/** Height in pixels of all the images of buttons*/
static final int BITMAP_HEIGHT = 27;
/** Coordinates of this button */
Coord mCoord = null;
/**
* Loads the image on this button and sets the button position on the minefield.
* @param coord Coordinates of the button.
* @param type Graphical view of the button
*/
public MineButton(Coord coord, GUI_FIELD type) {
initGraphics(coord, type);
this.setAcceptHoverEvents(true);
}
/**
* <P>Loads the image on this button and sets the button position on the minefield.</P>
*
* <P>All the bitmaps must have the same size. The left position of the bitmap
* is counted as the sum of (column * bitmap width) and (count of pairs up-down
* rows * half of bitmap width). Moreover the up buttons have the left position
* about half of the bitmap width more than the previous down buttons. The top
* position is counted as (count of pairs up-down rows * bitmap height).</P>
*
* @param coord Coordinates of the button.
* @param type Graphical view of the button
*/
void initGraphics(Coord coord, GUI_FIELD type) {
mCoord = coord;
boolean down = MinesUtils.isDownButton(coord.mX);
QPixmap picture = ResourceLoader.getMineButtonImage(type, down);
// set up the image
setShapeMode(QGraphicsPixmapItem.ShapeMode.MaskShape);
this.setPixmap(picture);
// set up the position
int left = (mCoord.mY * BITMAP_WIDTH) + ((mCoord.mX / 2) * (BITMAP_WIDTH / 2));
if(!down) {
left += (BITMAP_WIDTH / 2);
}
int top = (mCoord.mX / 2) * BITMAP_HEIGHT;
setPos(left, top);
}
/**
* Emits the mouse over signal.
* @param event Ignored.
*/
@Override
public void hoverMoveEvent(QGraphicsSceneHoverEvent event) {
mMouseMovedOver.emit(mCoord);
}
/**
* Sets the graphical view of the button according to the given button type.
* @param type Type of the button.
*/
public void setButtonType(GUI_FIELD type) {
boolean down = MinesUtils.isDownButton(mCoord.mX);
QPixmap picture = ResourceLoader.getMineButtonImage(type, down);
this.setPixmap(picture);
}
/**
* Emits the mouse left and right clicked signals.
* @param event Used for determining, which button was clicked.
*/
@Override
public void mousePressEvent(QGraphicsSceneMouseEvent event) {
MouseButton button = event.button();
switch(button) {
case LeftButton:
mLeftButtonPressed.emit(mCoord);
break;
case RightButton:
mRightButtonPressed.emit(mCoord);
break;
default:
break;
}
}
}