Browse Source

Allow cascading of spell tabs when a class can both Prepare and Learn spells on level up.

Sam Jaffe 8 years ago
parent
commit
4420d62b4e

+ 15 - 12
src/main/lombok/org/leumasjaffe/charsheet/view/level/LevelUpSpellPanel.java

@@ -30,8 +30,11 @@ import java.awt.GridBagConstraints;
 @SuppressWarnings("serial")
 @FieldDefaults(level=AccessLevel.PUBLIC, makeFinal=true)
 class LevelUpSpellPanel extends JPanel {
-
-	public static enum SpellPickType {
+	public static interface SpellPicker {
+		public List<List<Integer>> getSpellCounts(SelectSpellsPanel.Info info);
+		public Collection<DDSpell> getAvailableSpells(SelectSpellsPanel.Info info, int i);
+	}
+	public static enum SpellPickType implements SpellPicker {
 		LEARN {
 			@Override
 			public List<List<Integer>> getSpellCounts(SelectSpellsPanel.Info info) {
@@ -54,25 +57,24 @@ class LevelUpSpellPanel extends JPanel {
 			public Collection<DDSpell> getAvailableSpells(Info info, int i) {
 				return info.dclass.getSpellBook().get().spellsKnownAtLevel(i);
 			}
-		};
-		
-		public abstract List<List<Integer>> getSpellCounts(SelectSpellsPanel.Info info);
-		public abstract Collection<DDSpell> getAvailableSpells(SelectSpellsPanel.Info info, int i);
+		};		
 	}
 
 	int[] ready = {0};
 	@NonFinal int spellLevelsGrown = 0;
 	int oldHighestSpellLevel, newHighestSpellLevel, toLevel;
-	SpellPickType pick;
+	SpellPicker pick;
 	SelectSpellsPanel.Info info;
 	@Getter List<SelectSpellsPanel> panels;
 
-	public LevelUpSpellPanel(SpellPickType pick, SelectSpellsPanel.Info info, int toLevel, BoolArray readyCount) {
+	public LevelUpSpellPanel(SpellPicker pick, SelectSpellsPanel.Info info, 
+			BoolArray readyCount, int index) {
+		this.putClientProperty(SelectSpellsPanel.READY, false);
 		this.pick = pick;
 		this.info = info;
-		this.toLevel = toLevel;
+		this.toLevel = info.dclass.getLevel().value();
 		newHighestSpellLevel = info.dclass.getHighestSpellLevel(toLevel);
-		oldHighestSpellLevel = info.dclass.getHighestSpellLevel();
+		oldHighestSpellLevel = info.dclass.getHighestSpellLevel(toLevel-1);
 
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 0};
@@ -97,7 +99,7 @@ class LevelUpSpellPanel extends JPanel {
 		final Map<Integer, Integer> spells = getNewSpells(val);
 		final int sharedSlots = val.value();
 		for (int i = 0; i < newHighestSpellLevel; ++i) {
-			if (spells.get(i) < 0) continue;
+			if (spells.get(i) < 0) { panels.add(null); continue; }
 			++spellLevelsGrown;
 			SelectSpellsPanel lvl = new SelectSpellsPanel(info, i,
 					new LinkedHashSet<>(), Math.max(spells.get(i), sharedSlots), pick.getAvailableSpells(info, i),
@@ -106,7 +108,8 @@ class LevelUpSpellPanel extends JPanel {
 			lvl.addPropertyChangeListener(SelectSpellsPanel.READY, e -> {
 				if ((Boolean) e.getNewValue()) ++ready[0];
 				else --ready[0];
-				readyCount.data[1] = (ready[0] == spellLevelsGrown);
+				boolean b = readyCount.data[index] = (ready[0] == spellLevelsGrown);
+				this.putClientProperty(SelectSpellsPanel.READY, b);
 				ObserverDispatch.notifySubscribers(readyCount, this);
 			});
 			panel.add(lvl);

+ 63 - 16
src/main/lombok/org/leumasjaffe/charsheet/view/level/UpdateClassWithLevelPanel.java

@@ -1,12 +1,19 @@
 package org.leumasjaffe.charsheet.view.level;
 
+import static org.leumasjaffe.charsheet.view.level.LevelUpSpellPanel.SpellPickType.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 import java.util.function.Consumer;
 import java.util.stream.IntStream;
 
 import javax.swing.JPanel;
 
 import org.jdesktop.swingx.VerticalLayout;
+import org.leumasjaffe.charsheet.model.magic.DDSpell;
 import org.leumasjaffe.charsheet.view.magic.SelectSpellsPanel;
+import org.leumasjaffe.charsheet.view.magic.SelectSpellsPanel.Info;
 import org.leumasjaffe.charsheet.view.skills.SkillLevelUpPanel;
 import org.leumasjaffe.function.VoidVoidFunction;
 import org.leumasjaffe.observer.Observable;
@@ -15,6 +22,7 @@ import org.leumasjaffe.observer.ObserverDispatch;
 
 import lombok.AccessLevel;
 import lombok.experimental.FieldDefaults;
+import lombok.experimental.NonFinal;
 
 import java.awt.GridBagLayout;
 import javax.swing.JTabbedPane;
@@ -31,33 +39,37 @@ import javax.swing.JLabel;
 class UpdateClassWithLevelPanel extends JPanel {
 	@FieldDefaults(level=AccessLevel.PUBLIC, makeFinal=true)
 	public class BoolArray extends Observable {
-		boolean data[] = new boolean[] {false, false};
+		boolean data[] = new boolean[] {false, false, false};
 	}
 	BoolArray readyCount = new BoolArray();
 	ObservableListener<Consumer<Boolean>, BoolArray> listener;
+	JTabbedPane tabbedPane;
+	@NonFinal LevelUpSpellPanel learnSpells = null;
+	
 	public UpdateClassWithLevelPanel(LevelUpClassInfo info, VoidVoidFunction back,
 			Consumer<Boolean> setReady) {
+		info.ddClass.getLevel().value(info.toLevel);
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 0};
 		gridBagLayout.rowHeights = new int[]{0, 0, 0};
 		gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
 		gridBagLayout.rowWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
 		setLayout(gridBagLayout);
-		
-		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
+
+		tabbedPane = new JTabbedPane(JTabbedPane.TOP);
 		GridBagConstraints gbc_tabbedPane = new GridBagConstraints();
 		gbc_tabbedPane.insets = new Insets(0, 0, 5, 0);
 		gbc_tabbedPane.fill = GridBagConstraints.BOTH;
 		gbc_tabbedPane.gridx = 0;
 		gbc_tabbedPane.gridy = 0;
 		add(tabbedPane, gbc_tabbedPane);
-		
+
 		JPanel features = new JPanel(new VerticalLayout(2));
 		info.ddClass.getBase().getFeatures(info.toLevel).forEach(prop -> {
 			features.add(new JLabel(prop.getName()));
 		});
 		tabbedPane.addTab("Features", null, features, null);
-		
+
 		JPanel skills = new SkillLevelUpPanel(info.ddCharacter, info.ddClass) {
 			@Override public void setIsReady(boolean b) {
 				readyCount.data[0] = b;
@@ -65,23 +77,35 @@ class UpdateClassWithLevelPanel extends JPanel {
 			}
 		};
 		tabbedPane.addTab("Skills", null, skills, null);
-		
+
 		info.ddClass.getSpellBook().ifPresent(sb -> {
+			readyCount.data[1] = !sb.learnsSpells();
+			readyCount.data[2] = !sb.preparesSpells();
 			if (sb.learnsSpells()) {
-				JPanel spells = new LevelUpSpellPanel(LevelUpSpellPanel.SpellPickType.LEARN,
+				LevelUpSpellPanel spells = new LevelUpSpellPanel(LEARN,
 						new SelectSpellsPanel.Info(info.ddCharacter, info.ddClass),
-						info.toLevel, readyCount);
+						readyCount, 1);
 				tabbedPane.addTab("Learn Spells", null, spells, null);
+				if (sb.preparesSpells()) {
+					// TODO: use Observable?
+					spells.addPropertyChangeListener(SelectSpellsPanel.READY, e -> {
+						if ((Boolean) e.getNewValue()) {
+							createPrepareLearnedSpellPanel(info, spells);
+						} else {
+							tabbedPane.remove(learnSpells);
+							learnSpells = null;
+						}
+					});
+				}
 			}
-			// FIXME: needs to get the newly learned spells
-			if (sb.preparesSpells()) {
-				JPanel spells = new LevelUpSpellPanel(LevelUpSpellPanel.SpellPickType.PREPARE,
+			else if (sb.preparesSpells()) {
+				LevelUpSpellPanel spells = new LevelUpSpellPanel(PREPARE,
 						new SelectSpellsPanel.Info(info.ddCharacter, info.ddClass),
-						info.toLevel, readyCount);
+						readyCount, 2);
 				tabbedPane.addTab("Prepare Spells", null, spells, null);
 			}
 		});
-		
+
 		JPanel panel = new JPanel();
 		GridBagConstraints gbc_panel = new GridBagConstraints();
 		gbc_panel.fill = GridBagConstraints.BOTH;
@@ -94,7 +118,7 @@ class UpdateClassWithLevelPanel extends JPanel {
 		gbl_panel.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
 		gbl_panel.rowWeights = new double[]{0.0, Double.MIN_VALUE};
 		panel.setLayout(gbl_panel);
-		
+
 		JButton btnBack = new JButton("Back");
 		GridBagConstraints gbc_btnBack = new GridBagConstraints();
 		gbc_btnBack.insets = new Insets(0, 0, 0, 5);
@@ -102,17 +126,40 @@ class UpdateClassWithLevelPanel extends JPanel {
 		gbc_btnBack.gridy = 0;
 		panel.add(btnBack, gbc_btnBack);
 		btnBack.addActionListener(e -> back.apply());
-		
+
 		Component horizontalGlue = Box.createHorizontalGlue();
 		GridBagConstraints gbc_horizontalGlue = new GridBagConstraints();
 		gbc_horizontalGlue.gridx = 1;
 		gbc_horizontalGlue.gridy = 0;
 		panel.add(horizontalGlue, gbc_horizontalGlue);
-		
+
 		listener = new ObservableListener<>(setReady, (c, v) -> {
 			c.accept(IntStream.range(0, v.data.length)
 					.mapToObj(i -> v.data[i]).allMatch(b -> b));
 		});
 		listener.setObserved(readyCount);
 	}
+
+	private void createPrepareLearnedSpellPanel(LevelUpClassInfo info, LevelUpSpellPanel spells) {
+		LevelUpSpellPanel.SpellPicker pick = new LevelUpSpellPanel.SpellPicker() {
+			@Override
+			public List<List<Integer>> getSpellCounts(Info info) {
+				return PREPARE.getSpellCounts(info);
+			}
+
+			@Override
+			public Collection<DDSpell> getAvailableSpells(Info info, int i) {
+				final Collection<DDSpell> start = new ArrayList<>(PREPARE.getAvailableSpells(info, i));
+				if (spells.getPanels().get(i) != null) {
+					start.addAll(spells.getPanels().get(i).getPrepared());
+				}
+				return start;
+			}
+		};
+
+		learnSpells = new LevelUpSpellPanel(pick,
+				new SelectSpellsPanel.Info(info.ddCharacter, info.ddClass),
+				readyCount, 2);
+		tabbedPane.addTab("Prepare Spells", null, learnSpells, null);
+	}
 }

+ 0 - 4
src/main/lombok/org/leumasjaffe/charsheet/view/magic/SelectPreparedSpellsPanel.java

@@ -20,8 +20,4 @@ class SelectPreparedSpellsPanel extends SelectSpellsPanel {
 		this(chara, level, dclass, ((Prepared) dclass.getSpellBook().get()));
 	}
 
-	public SelectPreparedSpellsPanel(SelectSpellsPanel.Info info, int level) {
-		this(info.chara, level, info.dclass);
-	}
-
 }

+ 1 - 1
src/main/lombok/org/leumasjaffe/charsheet/view/magic/SelectSpellsPanel.java

@@ -99,12 +99,12 @@ public class SelectSpellsPanel extends JPanel {
 			Collection<DDSpell> avail, boolean allowsDuplicates, IntValue sharedValue) {
 		this.allowsDuplicates = allowsDuplicates;
 		this.sharedValue = sharedValue;
-		putClientProperty(READY, true);
 		final DDSpellbook spellBook = dclass.getSpellBook().get();
 		this.prepared = new ArrayList<>(prepared);
 		final List<DDSpell> known = new ArrayList<>(avail);
 		this.modelPrepared = new SelectSpellModel(createPrepareModel(prepared, toPrepare));
 		this.modelKnown = new SelectSpellModel(known.stream().map(DDSpell::getName).toArray());
+		putClientProperty(READY, countNone() == 0);
 		sharedValue.value(sharedValue.value() - this.modelPrepared.data.length + countNone());
 		
 		GridBagLayout gridBagLayout = new GridBagLayout();