/* * Copyright (c) 2003-onwards Shaven Puppy Ltd * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of 'Shaven Puppy' nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.puppygames.applet.screens; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.puppygames.applet.Area; import net.puppygames.applet.Game; import net.puppygames.applet.PlayerSlot; import net.puppygames.applet.Res; /** * A dialog screen that allows users to select, create, or delete player slots. Slots * are shown using SlotEffects. */ public class SlotScreen extends DialogScreen implements SlotEffectListener { private static SlotScreen instance; /** max slots */ private static final int maxSlots = 6; private static final String ID_NEW = "new"; private static final String ID_DELETE = "delete"; private static final String ID_RENAME = "rename"; private static final String ID_SLOT_ORIGIN = "slot_origin"; /** Slot class */ private String slotClass; /** Gap between slots, vertically */ private int gap; /** The slot effects */ private transient List<SlotEffect> slots; /** Slot class */ private transient Class<? extends PlayerSlot> slotClazz; /** Currently selected slot index */ private transient int selectedIndex; private transient Area slotOriginArea; /** * C'tor * @param name */ public SlotScreen(String name) { super(name); } @Override protected void doRegister() { assert instance == null; instance = this; } @Override protected void doDeregister() { assert instance == this; instance = null; } /** * Show the slot management screen */ public static void show() { if (!instance.isCreated()) { instance.create(); } instance.open(); } @Override protected void doCreateScreen() { try { slotClazz = (Class<? extends PlayerSlot>) Class.forName(slotClass); } catch (Exception e) { e.printStackTrace(System.err); } slotOriginArea = getArea(ID_SLOT_ORIGIN); } @Override protected void doOnOpen() { rebuild(); } private void rebuild() { if (slots != null) { for (Iterator<SlotEffect> i = slots.iterator(); i.hasNext(); ) { SlotEffect se = i.next(); se.remove(); } slots = null; } List<PlayerSlot> playerSlots = PlayerSlot.getSlots(); slots = new ArrayList<SlotEffect>(playerSlots.size()); int y = slotOriginArea.getBounds().getY(); for (PlayerSlot ps : playerSlots) { try { SlotEffect se = (SlotEffect) slotClazz.newInstance(); se.setSlot(ps); se.setLocation(slotOriginArea.getBounds().getX(), y); se.spawn(this); se.setSlotEffectListener(this); if (ps.equals(Game.getPlayerSlot())) { se.setSelected(true); } slots.add(se); y -= gap; } catch (Exception e) { e.printStackTrace(System.err); } } selectedIndex = -2; // Force change // Find the current slot int idx = -1; for (Iterator<SlotEffect> i = slots.iterator(); i.hasNext(); ) { SlotEffect se = i.next(); idx ++; if (se.isSelected()) { break; } } setSelectedIndex(idx); } @Override protected void onClicked(String id) { if (ID_NEW.equals(id)) { EnterNameDialog.show(true, new Runnable() { @Override public void run() { if (EnterNameDialog.isOKClicked()) { close(); } } }); } else if (ID_DELETE.equals(id)) { deleteSelected(); } else if (ID_RENAME.equals(id)) { renameSelected(); } else if (CANCEL.equals(id)) { if (selectedIndex != -1) { SlotEffect se = slots.get(selectedIndex); Game.setPlayerSlot(se.getSlot()); close(); } } } /** * Delete the currently selected slot, and select the one that comes up next. */ protected void deleteSelected() { if (selectedIndex == -1) { return; } final SlotEffect se = slots.get(selectedIndex); String msg = Game.getMessage("lwjglapplets.slotscreen.delete_message"); msg = msg.replace("[slot]", se.getSlot().getName().toUpperCase()); Res.getDeleteYesCancelDialog().doModal(Game.getMessage("lwjglapplets.slotscreen.delete_title"), msg, new Runnable() { @Override public void run() { int option = Res.getDeleteYesCancelDialog().getOption(); if (option == DialogScreen.OK_OPTION || option == DialogScreen.YES_OPTION) { se.getSlot().delete(); if (selectedIndex == slots.size() - 1) { selectedIndex--; } if (selectedIndex == -1) { Game.setPlayerSlot(null); assert false; // We shouldn't really ever get here as delete is supposed to have been enabled... } else { PlayerSlot slot = slots.get(selectedIndex).getSlot(); System.out.println("Setting player slot to " + slot.getName()); Game.setPlayerSlot(slot); } rebuild(); } } }); } /** * Rename the currently selected slot. Not yet implemented */ protected void renameSelected() { } @Override protected void doCleanup() { slots = null; } @Override public void onSlotEffectChanged(SlotEffect effect) { if (effect.isSelected()) { setSelectedIndex(slots.indexOf(effect)); // Deselect all the others for (SlotEffect se : slots) { if (se != effect) { se.setSelected(false); } } } } @Override public void onSlotEffectEdited(SlotEffect effect) { // TODO Not yet implemented } /** * Sets the currently selected slot * @param newIndex */ public void setSelectedIndex(int newIndex) { if (selectedIndex != newIndex) { selectedIndex = newIndex; enableControls(); } } protected void enableControls() { setEnabled(ID_NEW, slots.size() < maxSlots); setEnabled(ID_DELETE, selectedIndex != -1 && slots.size() > 1); setEnabled(ID_RENAME, selectedIndex != -1); setEnabled(CANCEL, selectedIndex != -1 || (selectedIndex == -1 && Game.getPlayerSlot() != null && Game.getPlayerSlot().exists())); } }