Add shift+click multi-select to custom quest format dialog

This commit is contained in:
Krazy
2017-06-24 04:57:11 +00:00
parent 98fc81cc7d
commit a6993eae8e
2 changed files with 258 additions and 182 deletions

View File

@@ -41,28 +41,38 @@ public class DialogChooseSets {
List<FCheckBox> otherSets = new ArrayList<>();
for (CardEdition ce : editions) {
String code = ce.getCode();
FCheckBox box = new FCheckBox(String.format("%s (%s)", ce.getName(), code));
box.setName(code);
box.setSelected(null != preselectedSets && preselectedSets.contains(code));
box.setEnabled(null == unselectableSets || !unselectableSets.contains(code));
switch (ce.getType()) {
case CORE: coreSets.add(box); break;
case EXPANSION: expansionSets.add(box); break;
default: otherSets.add(box); break;
}
case CORE:
coreSets.add(box);
break;
case EXPANSION:
expansionSets.add(box);
break;
default:
otherSets.add(box);
break;
}
FPanel p = new FPanel(new MigLayout("insets 0, gap 0, center, wrap 3"));
p.setOpaque(false);
p.setBackgroundTexture(FSkin.getIcon(FSkinProp.BG_TEXTURE));
}
p.add(new FLabel.Builder().text("Choose sets").fontSize(18).build(), "center, span, wrap, gaptop 10");
FPanel panel = new FPanel(new MigLayout("insets 0, gap 0, center, wrap 3"));
panel.setOpaque(false);
panel.setBackgroundTexture(FSkin.getIcon(FSkinProp.BG_TEXTURE));
panel.add(new FLabel.Builder().text("Choose sets").fontSize(18).build(), "center, span, wrap, gaptop 10");
String constraints = "aligny top";
p.add(makeCheckBoxList(coreSets, "Core sets", true), constraints);
p.add(makeCheckBoxList(expansionSets, "Expansions", false), constraints);
p.add(makeCheckBoxList(otherSets, "Other sets", false), constraints);
panel.add(makeCheckBoxList(coreSets, "Core sets", true), constraints);
panel.add(makeCheckBoxList(expansionSets, "Expansions", false), constraints);
panel.add(makeCheckBoxList(otherSets, "Other sets", false), constraints);
final JPanel overlay = FOverlay.SINGLETON_INSTANCE.getPanel();
overlay.setLayout(new MigLayout("insets 0, gap 0, wrap, ax center, ay center"));
@@ -99,22 +109,28 @@ public class DialogChooseSets {
southPanel.add(btnOk, "center, w 40%, h 20!");
southPanel.add(btnCancel, "center, w 40%, h 20!");
p.add(southPanel, "dock south, gapBottom 10");
panel.add(southPanel, "dock south, gapBottom 10");
overlay.add(p);
p.getRootPane().setDefaultButton(btnOk);
overlay.add(panel);
panel.getRootPane().setDefaultButton(btnOk);
SOverlayUtils.showOverlay();
}
public void setOkCallback(Runnable onOk) {
okCallback = onOk;
}
// result accessors
public List<String> getSelectedSets() { return selectedSets; }
public boolean getWantReprints() { return wantReprints; }
public List<String> getSelectedSets() {
return selectedSets;
}
public boolean getWantReprints() {
return wantReprints;
}
private JPanel makeCheckBoxList(List<FCheckBox> sets, String title, boolean focused) {
choices.addAll(sets);
final FCheckBoxList<FCheckBox> cbl = new FCheckBoxList<>(false);
cbl.setListData(sets.toArray(new FCheckBox[sets.size()]));
@@ -134,19 +150,22 @@ public class DialogChooseSets {
pnl.add(new FLabel.Builder().text(title).build());
pnl.add(new FScrollPane(cbl, true));
return pnl;
}
private void handleOk() {
for (FCheckBox box : choices) {
if (box.isSelected()) {
selectedSets.add(box.getName());
}
wantReprints = cbWantReprints.isSelected();
}
if (null != okCallback) {
okCallback.run();
}
}
}

View File

@@ -1,45 +1,90 @@
package forge.toolbox;
import java.awt.Component;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
/**
* A list of FCheckBox items using Forge skin properties.
* Call setListData() with an array of FCheckBox items to populate.
*
* <p>
* based on code at http://www.devx.com/tips/Tip/5342
*/
@SuppressWarnings("serial")
public class FCheckBoxList<E> extends JList<E> {
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
private static final Border NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
private int lastClickedIndex = 0;
private int currentShiftSelectionMinIndex = Integer.MAX_VALUE;
private int currentShiftSelectionMaxIndex = -1;
private int currentHighlightMinIndex = Integer.MAX_VALUE;
private int currentHighlightMaxIndex = -1;
private boolean shiftSelectShouldCheckBox = true;
public FCheckBoxList(final boolean keepSelectionWhenFocusLost) {
setCellRenderer(new CellRenderer<E>());
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(final MouseEvent e) {
final int index = locationToIndex(e.getPoint());
if (index != -1) {
if (e.isShiftDown()) {
int min = Math.min(lastClickedIndex, index);
int max = Math.max(lastClickedIndex, index);
if (index == lastClickedIndex) {
currentHighlightMinIndex = lastClickedIndex;
currentHighlightMaxIndex = lastClickedIndex;
} else if (index > lastClickedIndex) {
currentHighlightMinIndex = lastClickedIndex;
currentHighlightMaxIndex = index;
} else if (index < lastClickedIndex) {
currentHighlightMinIndex = index;
currentHighlightMaxIndex = lastClickedIndex;
}
currentShiftSelectionMinIndex = Math.min(min, currentShiftSelectionMinIndex);
currentShiftSelectionMaxIndex = Math.max(max, currentShiftSelectionMaxIndex);
for (int i = currentShiftSelectionMinIndex; i <= currentShiftSelectionMaxIndex; i++) {
final FCheckBox checkbox = (FCheckBox) getModel().getElementAt(i);
if (shiftSelectShouldCheckBox) {
checkbox.setSelected(!shiftSelectShouldCheckBox);
}
}
for (int i = min; i <= max; i++) {
final FCheckBox checkbox = (FCheckBox) getModel().getElementAt(i);
checkbox.setSelected(shiftSelectShouldCheckBox);
}
} else {
final FCheckBox checkbox = (FCheckBox) getModel().getElementAt(index);
if (checkbox.isEnabled()) {
checkbox.setSelected(!checkbox.isSelected());
shiftSelectShouldCheckBox = checkbox.isSelected();
lastClickedIndex = index;
currentShiftSelectionMinIndex = currentHighlightMinIndex = Integer.MAX_VALUE;
currentShiftSelectionMaxIndex = currentHighlightMaxIndex = -1;
}
}
repaint();
}
}
}
});
@@ -70,7 +115,7 @@ public class FCheckBoxList<E> extends JList<E> {
@Override
public void focusGained(final FocusEvent arg0) {
if (-1 == getSelectedIndex()) {
if (getSelectedIndex() == -1) {
setSelectedIndex(lastSelectedIdx);
}
}
@@ -78,19 +123,31 @@ public class FCheckBoxList<E> extends JList<E> {
}
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
protected class CellRenderer<E1> implements ListCellRenderer<E1> {
@Override
public Component getListCellRendererComponent(final JList<? extends E1> list, final E1 value, final int index, final boolean isSelected, final boolean cellHasFocus) {
final FCheckBox checkbox = (FCheckBox) value;
checkbox.setBackground(isSelected ? getSelectionBackground() : getBackground());
if (index >= currentHighlightMinIndex && index <= currentHighlightMaxIndex) {
checkbox.setOpaque(true);
} else {
checkbox.setOpaque(false);
}
checkbox.setForeground(isSelected ? getSelectionForeground() : getForeground());
checkbox.setBackground(getSelectionBackground());
checkbox.setFont(getFont());
checkbox.setFocusPainted(false);
checkbox.setBorderPainted(true);
checkbox.setBorder(isSelected ? UIManager.getBorder("List.focusCellHighlightBorder") : noFocusBorder);
checkbox.setBorder(isSelected ? UIManager.getBorder("List.focusCellHighlightBorder") : NO_FOCUS_BORDER);
return checkbox;
}
}
}