Package com.jcloisterzone.ui.controls

Source Code of com.jcloisterzone.ui.controls.ActionPanel

package com.jcloisterzone.ui.controls;

import static com.jcloisterzone.ui.controls.ControlPanel.CORNER_DIAMETER;
import static com.jcloisterzone.ui.controls.ControlPanel.PANEL_WIDTH;

import java.awt.Cursor;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;

import javax.swing.ImageIcon;

import com.jcloisterzone.Player;
import com.jcloisterzone.action.AbbeyPlacementAction;
import com.jcloisterzone.action.PlayerAction;
import com.jcloisterzone.action.TilePlacementAction;
import com.jcloisterzone.ui.Client;
import com.jcloisterzone.ui.grid.ForwardBackwardListener;

public class ActionPanel extends FakeComponent implements RegionMouseListener, ForwardBackwardListener {

    public static final int FAKE_ACTION_SIZE = 62;
    public static final int LINE_HEIGHT = 30;
    public static final int PADDING = 3;
    public static final int LEFT_MARGIN = 10;
    public static final double ACTIVE_SIZE_RATIO = 1.375;

    private boolean active;
    private PlayerAction<?>[] actions;
    private int selectedActionIndex = -1;

    //cached scaled smooth images
    private Image[] selected, deselected;
    private int imgOffset = 0;
    private boolean refreshImages, refreshMouseRegions;

    private String fakeAction;
    private Image fakeActionImage;

    public ActionPanel(Client client) {
        super(client);
    }

    private void repaint() {
        client.getGridPanel().repaint();
    }

    public PlayerAction<?>[] getActions() {
        return actions;
    }

    public void setActions(boolean active, PlayerAction<?>[] actions) {
        this.active = active;
        selected = new Image[actions.length];
        deselected = new Image[actions.length];
        refreshImages = true;
        refreshMouseRegions = true;
        this.actions = actions;
        if (actions.length > 0 && active) {
            setSelectedActionIndex(0);
        }
        repaint();
    }


    public void refreshImageCache() {
        //refresh is executed in AWT thread
        refreshImages = true;
        repaint();
    }

    private void doRefreshImageCache() {
        if (actions == null || actions.length == 0) {
            selected = null;
            deselected = null;
        }

        int maxIconSize = 40;
        imgOffset = 0;

        if (actions[0] instanceof TilePlacementAction) {
            imgOffset = -10;
            maxIconSize = 62;
        } else if (actions[0] instanceof AbbeyPlacementAction) {
            imgOffset = 4;
            maxIconSize = 52;
        else {
            maxIconSize = 40;
        }

        int availableWidth = ControlPanel.PANEL_WIDTH - LEFT_MARGIN - (actions.length-1)*PADDING;
        double units = actions.length + (ACTIVE_SIZE_RATIO-1.0);
        int baseSize = Math.min(maxIconSize, (int) Math.floor(availableWidth / units));
        int activeSize = (int) (baseSize * ACTIVE_SIZE_RATIO);

        Player activePlayer = client.getGame().getActivePlayer();
        for (int i = 0; i < actions.length; i++) {
            selected[i] = new ImageIcon(
                actions[i].getImage(activePlayer, true).getScaledInstance(activeSize, activeSize, Image.SCALE_SMOOTH)
            ).getImage();
            deselected[i] = new ImageIcon(
                actions[i].getImage(activePlayer, false).getScaledInstance(baseSize, baseSize, Image.SCALE_SMOOTH)
            ).getImage();
        }
    }

    public void clearActions() {
        deselectAction();
        this.actions = null;
        this.selectedActionIndex = -1;
        refreshImages = true;
        refreshMouseRegions = true;
        fakeAction = null;
        active = false;
        repaint();
    }



    public void forward() {
        if (active && selectedActionIndex != -1) getSelectedAction().forward();
    }

    public void backward() {
        if (active && selectedActionIndex != -1) getSelectedAction().backward();
    }

    public void rollAction(int change) {
        if (active) {
            if (actions.length == 0) return;
            int idx = (selectedActionIndex + change + actions.length) % actions.length;
            setSelectedActionIndex(idx);
            repaint();
        }
    }

    private void deselectAction() {
        if (this.selectedActionIndex != -1) {
            PlayerAction<?> prev = actions[this.selectedActionIndex];
            prev.deselect();
        }
    }

    private void setSelectedActionIndex(int selectedActionIndex) {
        deselectAction();
        this.selectedActionIndex = selectedActionIndex;
        PlayerAction<?> action = actions[selectedActionIndex];
        action.select(active);
    }

    public PlayerAction<?> getSelectedAction() {
        return actions[selectedActionIndex];
    }

    @Override
    public void paintComponent(Graphics2D g2) {
        super.paintComponent(g2);

        g2.setColor(ControlPanel.PLAYER_BG_COLOR);
        g2.fillRoundRect(0, 0, PANEL_WIDTH+CORNER_DIAMETER, LINE_HEIGHT, CORNER_DIAMETER, CORNER_DIAMETER);

        int x = LEFT_MARGIN;

        if (fakeActionImage != null) {
            g2.drawImage(fakeActionImage, x, ((LINE_HEIGHT-FAKE_ACTION_SIZE) / 2)+imgOffset, FAKE_ACTION_SIZE, FAKE_ACTION_SIZE, null);
        }

        if (actions == null || actions.length == 0) return;

        //possible race condition - (but AtomBoolean cannot be used, too slow for painting)
        boolean refreshImages = this.refreshImages;
        this.refreshImages = false;
        boolean refreshMouseRegions = this.refreshMouseRegions;
        this.refreshMouseRegions = false;

        if (refreshImages) {
            doRefreshImageCache();
        }

        if (refreshMouseRegions) {
            getMouseRegions().clear();
        }

        for (int i = 0; i < actions.length; i++) {
            boolean active = (i == selectedActionIndex);

            Image img = active ? selected[i] : deselected[i];
            int size = img.getWidth(null);
            int iy = (LINE_HEIGHT-size) / 2;

            if (refreshMouseRegions && selectedActionIndex != -1) {
                getMouseRegions().add(new MouseListeningRegion(new Rectangle(x, iy+imgOffset, size, size), this, i));
            }
            g2.drawImage(img, x, iy+imgOffset, size, size, null);
            x += size + PADDING;
        }
    }

    @Override
    public void mouseClicked(MouseEvent e, MouseListeningRegion origin) {
        if (e.getButton() == MouseEvent.BUTTON1) {
            Integer i = (Integer) origin.getData();
            setSelectedActionIndex(i);
        }
    }

    @Override
    public void mouseEntered(MouseEvent e, MouseListeningRegion origin) {
        Integer i = (Integer) origin.getData();
        if (i != selectedActionIndex) {
            client.getGridPanel().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        }
    }

    @Override
    public void mouseExited(MouseEvent e, MouseListeningRegion origin) {
        client.getGridPanel().setCursor(Cursor.getDefaultCursor());
    }

    public String getFakeAction() {
        return fakeAction;
    }

    public void setFakeAction(String fakeAction) {
        this.fakeAction = fakeAction;
        if (fakeAction == null) {
            fakeActionImage = null;
        } else {
            fakeActionImage = client.getFigureTheme().getLayeredImage("actions/"+fakeAction, null).getScaledInstance(FAKE_ACTION_SIZE, FAKE_ACTION_SIZE, Image.SCALE_SMOOTH);
        }
        repaint();
    }


}
TOP

Related Classes of com.jcloisterzone.ui.controls.ActionPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.