/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package thegame.gui;
import java.awt.Color;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import net.sf.jiga.xtended.impl.Sf3RenderableImpl;
import net.sf.jiga.xtended.impl.Sprite;
import net.sf.jiga.xtended.impl.game.RenderingScene;
import net.sf.jiga.xtended.impl.game.physics.Player;
import net.sf.jiga.xtended.kernel.BitStack;
import thegame.FieldGui;
/**
* FieldGui component that shows up a rolling (vertical) / grid (horizontal)
* menu.
*
* @author www.b23prodtm.info
*/
public class SelectionMenuComponent extends GameMenuElement implements KeyListener {
private static BitStack _layoutBits = new BitStack();
public final static int PADDING = 10;
public final static int VERTICAL_LAYOUT = _layoutBits._newBitRange();
public final static int HORIZONTAL_LAYOUT = _layoutBits._newBitRange();
List<SelectionMenuCell> menu;
Paint gradient;
int layout;
public Selectable_ selectable;
/**
* @param selectionMode 1 is the default only one selection; 2 and above for
* multiple selections; 0 for disabling the menu.
*/
public void setMultipleSelectionMode(int selectionMode) {
selectable.selectionMode = selectionMode;
}
/**
* creates a new instance.
*/
public SelectionMenuComponent(FieldGui gui, String name, List<? extends SelectionMenuCell> menu, int layout) {
this(gui, name, null, menu, layout);
}
/**
* creates a new instance. the default layout VERTICAL_LAYOUT is used.
*/
public SelectionMenuComponent(FieldGui gui, String name, List<? extends SelectionMenuCell> menu) {
this(gui, name, null, menu, VERTICAL_LAYOUT);
}
/**
* creates a new instance. the default layout VERTICAL_LAYOUT is used.
*/
public SelectionMenuComponent(FieldGui gui, String name, SelectionMenuComponent parent, List<? extends SelectionMenuCell> menu) {
this(gui, name, parent, menu, VERTICAL_LAYOUT);
}
FieldGui gui;
/**
* creates a new instance.
*
* @param name the name to display as the title
* @param parent the parent menu, or null
* @param menu the menu cells
* @param layout the layout to use; must be a combination of the available
* layouts and displays
* @see #HORIZONTAL_LAYOUT
* @see #VERTICAL_LAYOUT
* @param quitMenuAction
* @see SelectionMenuComponent(String, SelectionMenuCell[])
*/
public SelectionMenuComponent(FieldGui gui, String name, SelectionMenuComponent parent, List<? extends SelectionMenuCell> menu, int layout) {
super(parent, new Sf3RenderableImpl(), name);
this.gui = gui;
assert layout != 0 : getClass().getName() + " INVALID SELECTED LAYOUT !";
this.layout = layout;
this.menu = new ArrayList<SelectionMenuCell>();
if (parent instanceof SelectionMenuComponent) {
this.menu.add(new SelectionMenuCell(gui, "back to " + parent.name, new Runnable() {
public void run() {
SelectionMenuComponent.this.gui.getMenu_handler().current = (SelectionMenuComponent) SelectionMenuComponent.this.parent;
}
}, null));
}
this.menu.addAll(menu);
/*
* keep odd count to reach a middle while refreshing
*/
if (this.menu.size() % 2 == 0) {
this.menu.add(new SelectionMenuCell(gui, "::" + name + "::", null, null));
}
if ((layout & HORIZONTAL_LAYOUT) != 0 && (layout & VERTICAL_LAYOUT) != 0) {
selectable = new SelectionMenuComponent_TABLE(this);
} else {
selectable = new SelectionMenuComponent_LIST(this);
}
selectable.reset();
}
public SelectionMenuCell[] getMenuCells() {
return menu.toArray(new SelectionMenuCell[]{});
}
public int getFocusedMenu() {
int i = 0;
synchronized (menu) {
for (Iterator<SelectionMenuCell> c = menu.iterator(); c.hasNext(); i++) {
if (c.next().isCellHasFocus()) {
return i;
}
}
}
return 0;
}
public List<SelectionMenuCell> getSelectedCells() {
List<SelectionMenuCell> list = new ArrayList<SelectionMenuCell>();
synchronized (menu) {
for (SelectionMenuCell c : menu) {
if (c.isSelected()) {
list.add(c);
}
}
}
return list;
}
private Rectangle gradientBounds = new Rectangle();
Sprite offscreen = null;
private int numCellsToDisplay = 3;
/**
* note: it always keeps an odd count of displayed cells (for the VERTICAL
* LAYOUT)
*/
public void setNumCellsToDisplay(int numCellsToDisplay) {
this.numCellsToDisplay = numCellsToDisplay;
}
public int getNumCellsToDisplay() {
return numCellsToDisplay;
}
/**
* INTERNAL : renders immediatelly
*/
public void GLpaintComponent(RenderingScene gld, double z, int fx, Point fx_loc, Color fx_color) {
Rectangle menuBounds = getBounds();
Rectangle lastBounds = null;
int focusedIndex = getFocusedMenu();
if (gui.isDebugEnabled()) {
System.err.println("menu layout : " + layout);
}
if ((layout & VERTICAL_LAYOUT) != 0 && (layout & HORIZONTAL_LAYOUT) == 0) {
/**
* always keep odd count of displayed cells (menu.size() is already
* odd)
*/
numCellsToDisplay = Math.min(menu.size(), numCellsToDisplay + (numCellsToDisplay % 2));
List<SelectionMenuCell> ordered = new ArrayList<SelectionMenuCell>(menu);
/**
* reorder to put the focused menu index on the center of the menu
*/
Collections.rotate(ordered, (int) (Math.floor(.5f * ordered.size()) - focusedIndex));
/**
* cut to the desired size
*/
while (numCellsToDisplay < ordered.size()) {
ordered = ordered.subList(1, ordered.size() - 1);
}
/**
* paint cells
*/
for (SelectionMenuCell cell : ordered) {
if (cell instanceof SelectionMenuCell) {
if (gui.isDebugEnabled()) {
System.err.println("menu cell : " + cell.name);
}
Rectangle cellBounds = new Rectangle(menuBounds.x, (int) (lastBounds instanceof Rectangle ? lastBounds.getMaxY() : menuBounds.y), menuBounds.width, (int) ((float) menuBounds.height / (float) menu.size()));
cellBounds.grow(-PADDING, -(int) ((float) PADDING / 2f));
cell.setBounds(cellBounds);
cell.GLpaintComponent(gld, z, fx, fx_loc, fx_color);
lastBounds = cellBounds;
}
}
}
if ((layout & VERTICAL_LAYOUT) != 0 && (layout & HORIZONTAL_LAYOUT) != 0) {
/**
* the characters selection panel
*/
int selectionWidth = gui.UISELECTIONWIDTH;
float pad = PADDING;
lastBounds = menuBounds;
int n = 0;
for (SelectionMenuCell cell : menu) {
if (cell instanceof SelectionMenuCell) {
Rectangle bounds = new Rectangle((n % selectionWidth) != 0 ? (int) (lastBounds.getMaxX() + pad) : menuBounds.x, (n % selectionWidth) != 0 || n == 0 ? lastBounds.y : (int) (lastBounds.getMaxY() + pad), gui.ICONSIZE.width, gui.ICONSIZE.height);
cell.setBounds(bounds);
cell.GLpaintComponent(gld, z, fx, fx_loc, fx_color);
lastBounds = bounds;
n++;
}
}
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
boolean b = false;
int kCode = e.getKeyCode();
if (Player._keyCodeMap.get(Player.key.ONE_LK) == kCode || Player._keyCodeMap.get(Player.key.ONE_LP) == kCode) {
kCode = KeyEvent.VK_ENTER;
}
if (Player._keyCodeMap.get(Player.key.ONE_MK) == kCode || Player._keyCodeMap.get(Player.key.ONE_MP) == kCode) {
kCode = KeyEvent.VK_ESCAPE;
}
switch (kCode) {
case KeyEvent.VK_UP:
if (selectable instanceof SelectionMenuComponent_LIST) {
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_UP);
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_INDEX_FOUND);
}
if (selectable instanceof SelectionMenuComponent_TABLE) {
selectable.newInput(((SelectionMenuComponent_TABLE) selectable).INPUT_UP);
}
b = true;
break;
case KeyEvent.VK_DOWN:
if (selectable instanceof SelectionMenuComponent_LIST) {
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_DOWN);
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_INDEX_FOUND);
}
if (selectable instanceof SelectionMenuComponent_TABLE) {
selectable.newInput(((SelectionMenuComponent_TABLE) selectable).INPUT_DOWN);
}
b = true;
break;
case KeyEvent.VK_RIGHT:
if (selectable instanceof SelectionMenuComponent_LIST) {
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_DOWN);
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_INDEX_FOUND);
}
if (selectable instanceof SelectionMenuComponent_TABLE) {
selectable.newInput(((SelectionMenuComponent_TABLE) selectable).INPUT_RIGHT);
}
b = true;
break;
case KeyEvent.VK_LEFT:
if (selectable instanceof SelectionMenuComponent_LIST) {
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_UP);
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_INDEX_FOUND);
}
if (selectable instanceof SelectionMenuComponent_TABLE) {
selectable.newInput(((SelectionMenuComponent_TABLE) selectable).INPUT_LEFT);
}
b = true;
break;
case KeyEvent.VK_ESCAPE:
case KeyEvent.VK_BACK_SPACE:
if (selectable instanceof SelectionMenuComponent_LIST) {
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_ESC_DELETE);
}
if (selectable instanceof SelectionMenuComponent_TABLE) {
selectable.newInput(((SelectionMenuComponent_TABLE) selectable).INPUT_ESC_DELETE);
}
b = true;
break;
case KeyEvent.VK_ENTER:
case KeyEvent.VK_SPACE:
if (selectable instanceof SelectionMenuComponent_LIST) {
selectable.newInput(((SelectionMenuComponent_LIST) selectable).INPUT_ENTER_SPACE);
}
if (selectable instanceof SelectionMenuComponent_TABLE) {
selectable.newInput(((SelectionMenuComponent_TABLE) selectable).INPUT_ENTER_SPACE);
}
b = true;
break;
default:
break;
}
if (b) {
e.consume();
}
}
public void keyReleased(KeyEvent e) {
}
public void reset() {
selectable.reset();
}
}