/*
* Copyright (c) 2014 tabletoptool.com team.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* rptools.com team - initial implementation
* tabletoptool.com team - further development
*/
package com.t3.client.ui.macrobuttons.panels;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.Scrollable;
import javax.swing.SwingUtilities;
import com.t3.AppEvent;
import com.t3.AppEventListener;
import com.t3.client.TabletopTool;
import com.t3.client.ui.macrobuttons.buttongroups.AreaGroup;
import com.t3.client.ui.macrobuttons.buttongroups.ButtonGroup;
import com.t3.client.ui.macrobuttons.buttongroups.ButtonGroupPopupMenu;
import com.t3.client.ui.macrobuttons.buttons.MacroButton;
import com.t3.model.MacroButtonProperties;
import com.t3.model.ModelChangeEvent;
import com.t3.model.ModelChangeListener;
import com.t3.model.Token;
import com.t3.model.Zone;
import com.t3.model.Zone.Event;
import com.t3.util.guidreference.NullHelper;
import com.t3.util.guidreference.TokenReference;
@SuppressWarnings("serial")
public abstract class AbstractMacroPanel extends JPanel implements Scrollable, MouseListener, ModelChangeListener, AppEventListener {
private String panelClass = "";
private TokenReference token = null;
public void addArea(List<MacroButtonProperties> propertiesList, String label) {
add(new AreaGroup(propertiesList, label, this));
setLayout(new FlowLayout(FlowLayout.LEFT));
revalidate();
repaint();
}
public void addArea(TokenReference token) {
add(new AreaGroup(token, this));
setLayout(new FlowLayout(FlowLayout.LEFT));
revalidate();
repaint();
}
@Override
public Insets getInsets() {
return new Insets(0, 0, 0, 0);
}
public int getAvailableWidth() {
Dimension size = getParent().getSize();
Insets insets = getInsets();
return size.width - insets.left - insets.right;
}
@Override
public Dimension getPreferredSize() {
Dimension size = getParent().getSize();
FlowLayout layout = (FlowLayout) getLayout();
Insets insets = getInsets();
// This isn't exact, but hopefully it's close enough
int panelWidth = size.width - insets.left - insets.right;
int panelHeight = size.height - insets.top - insets.bottom;
int height = insets.top + insets.bottom + layout.getVgap();
for (Component c : getComponents()) {
Dimension cSize = c.getPreferredSize();
height += cSize.height + layout.getVgap();
}
height = Math.max(height, panelHeight); // fill the panel if it wouldn't already
Dimension prefSize = new Dimension(panelWidth, height);
return prefSize;
}
public String getPanelClass() {
return panelClass;
}
public void setPanelClass(String panelClass) {
this.panelClass = panelClass;
}
public Token getToken() {
return NullHelper.value(token);
}
public TokenReference getTokenReference() {
return this.token;
}
public void setToken(Token token) {
this.token=NullHelper.referenceToken(token);
}
protected void clear() {
removeAll();
revalidate();
repaint();
}
public abstract void reset();
// SCROLLABLE
@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 75;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return getPreferredSize().height < getParent().getSize().height;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 25;
}
// Override these mouse events in subclasses to specify component specific behavior.
@Override
public void mouseClicked(MouseEvent event) {
}
@Override
public void mousePressed(MouseEvent event) {
}
@Override
public void mouseReleased(MouseEvent event) {
if (SwingUtilities.isRightMouseButton(event)) {
if ("CampaignPanel".equals(getPanelClass()) && !TabletopTool.getPlayer().isGM()) {
return;
}
// open button group menu
new ButtonGroupPopupMenu(getPanelClass(), null, "", getToken()).show(this, event.getX(), event.getY());
}
}
@Override
public void mouseEntered(MouseEvent event) {
}
@Override
public void mouseExited(MouseEvent event) {
}
// currently only used for Impersonate/Selection panels to refresh when the token is removed or a macro changes
@Override
public void modelChanged(ModelChangeEvent event) {
if (event.eventType == Token.ChangeEvent.MACRO_CHANGED || event.eventType == Event.TOKEN_REMOVED) {
reset();
}
}
@Override
public void handleAppEvent(AppEvent event) {
Zone oldZone = (Zone) event.getOldValue();
Zone newZone = (Zone) event.getNewValue();
if (oldZone != null) {
oldZone.removeModelChangeListener(this);
}
newZone.addModelChangeListener(this);
reset();
}
public static void clearHotkeys(AbstractMacroPanel panel) {
for (int areaGroupCount = 0; areaGroupCount < panel.getComponentCount(); areaGroupCount++) {
AreaGroup area = (AreaGroup) panel.getComponent(areaGroupCount);
for (ButtonGroup group : area.getButtonGroups()) {
for (MacroButton nextButton : group.getButtons()) {
nextButton.clearHotkey();
}
}
}
}
}