package magic.ui.widget.duel.sidebar;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.Scrollable;
import magic.ui.IChoiceViewer;
import magic.ui.duel.viewerinfo.StackViewerInfo;
import magic.ui.screen.duel.game.SwingGameController;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
public class StackViewer extends JPanel implements IChoiceViewer {
private final SwingGameController controller;
private final Collection<StackButton> buttons;
private JScrollPane stackScrollPane;
private ScrollablePanel stackScrollablePanel;
public StackViewer(final SwingGameController controller) {
this.controller=controller;
controller.registerChoiceViewer(this);
buttons=new ArrayList<>();
refreshLayout();
setOpaque(false);
}
private void refreshLayout() {
stackScrollablePanel = new ScrollablePanel();
stackScrollablePanel.setLayout(new MigLayout("insets 0, gap 0, flowy"));
stackScrollablePanel.setOpaque(false);
stackScrollPane = new JScrollPane(stackScrollablePanel);
stackScrollPane.setMinimumSize(new Dimension(0, 0));
stackScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
stackScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
stackScrollPane.setBorder(null);
stackScrollPane.setOpaque(false);
stackScrollPane.getViewport().setOpaque(false);
removeAll();
setLayout(new MigLayout("insets 0, gap 0, flowy"));
add(stackScrollPane, "w 100%");
}
public void update() {
final int maxWidth = getWidth() - 30;
stackScrollablePanel.removeAll();
buttons.clear();
// Display stack items
final List<StackViewerInfo> stack = controller.getViewerInfo().getStack();
final int stackSize = stack.size();
for (int i = 0; i < stackSize; i++) {
final StackViewerInfo stackInfo = stack.get(i);
StackButton btn = new StackButton(controller, stackInfo, maxWidth, stackSize - i);
buttons.add(btn);
stackScrollablePanel.add(btn, "w 100%");
}
stackScrollablePanel.revalidate();
controller.setStackCount(buttons.size());
// set preferred size for layout manager.
int preferredHeight =
stackScrollablePanel.getPreferredSize().height;
setPreferredSize(new Dimension(getWidth(), preferredHeight));
showValidChoices(controller.getValidChoices());
}
@Override
public void showValidChoices(final Set<?> validChoices) {
for (final StackButton button : buttons) {
button.showValidChoices(validChoices);
}
}
/**
* By using a Scrollable panel in the ScrollPane the content will adjust
* correctly based on whether the vertical scrollbar is visible or not.
*/
@SuppressWarnings("serial")
private final class ScrollablePanel extends JPanel implements Scrollable {
@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return getFont().getSize();
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return getFont().getSize();
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
// we don't want to track the height, because we want to scroll vertically.
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
}