Support flipping cards on reward dialog

Prevent concurrent modification exception from opening overlay from background thread
This commit is contained in:
drdev
2015-12-14 18:29:51 +00:00
parent 46fe68d5b9
commit e89bc7e0be
4 changed files with 58 additions and 23 deletions

View File

@@ -223,6 +223,10 @@ public class ConquestRewardDialog extends FScrollPane {
for (int i = currentIndex; i < index; i++) {
cardRevealers.get(i).progress = 1;
}
//ensure current card in view
if (getScrollHeight() > getHeight() && index < cardCount) {
scrollIntoView(cardRevealers.get(index), PADDING);
}
}
currentIndex = index;
@@ -237,10 +241,11 @@ public class ConquestRewardDialog extends FScrollPane {
//skip remainder of animation
private void skip() {
currentIndex = cardRevealers.size();
for (int i = currentIndex; i < currentIndex; i++) {
int cardCount = cardRevealers.size();
for (int i = currentIndex; i < cardCount; i++) {
cardRevealers.get(i).progress = 1;
}
currentIndex = cardCount;
animation.stop();
}
@@ -256,18 +261,21 @@ public class ConquestRewardDialog extends FScrollPane {
private class CardRevealer extends FLabel {
private static final float DUPLICATE_ALPHA_COMPOSITE = 0.35f;
private static final float FLIP_DURATION = 0.85f;
private static final float FADE_DUPLICATE_DURATION = 0.1f; //give a brief interlude before the next flip
private final ConquestReward reward;
private float progress;
private CardRevealer(ConquestReward reward0) {
super(new FLabel.Builder().iconScaleFactor(1f));
super(new FLabel.Builder().iconScaleWithFont(true).iconScaleFactor(1));
reward = reward0;
if (reward.isDuplicate()) {
setFont(FSkinFont.get(20));
setIcon(FSkinImage.QUEST_COIN);
setAlignment(HAlignment.CENTER);
setText(String.valueOf(reward.getReplacementShards()));
}
}
@@ -291,23 +299,35 @@ public class ConquestRewardDialog extends FScrollPane {
float w = getWidth();
float h = getHeight();
if (progress > 0.9999f) { //account for floating point error
if (progress >= FLIP_DURATION) {
float fadeProgress = (progress - FLIP_DURATION) / FADE_DUPLICATE_DURATION;
if (reward.isDuplicate()) {
g.setAlphaComposite(DUPLICATE_ALPHA_COMPOSITE);
float alphaComposite = DUPLICATE_ALPHA_COMPOSITE;
if (fadeProgress < 1) {
alphaComposite += (1 - fadeProgress) * (1 - DUPLICATE_ALPHA_COMPOSITE);
}
g.setAlphaComposite(alphaComposite);
}
CardRenderer.drawCard(g, reward.getCard(), 0, 0, w, h, CardStackPosition.Top);
if (reward.isDuplicate()) {
g.resetAlphaComposite();
if (fadeProgress >= 1) {
drawContent(g, 0, 0, w, h);
}
}
else if (progress >= 0.5f) {
CardRenderer.drawCard(g, reward.getCard(), 0, 0, w, h, CardStackPosition.Top);
}
else {
float halfDuration = FLIP_DURATION / 2;
if (progress >= halfDuration) {
float flipWidth = w * (progress - halfDuration) / halfDuration;
CardRenderer.drawCard(g, reward.getCard(), (w - flipWidth) / 2, 0, flipWidth, h, CardStackPosition.Top);
}
else {
Texture cardBack = ImageCache.getImage(ImageKeys.getTokenKey(ImageKeys.HIDDEN_CARD), true);
if (cardBack != null) {
g.drawImage(cardBack, 0, 0, w, h);
float flipWidth = w * (halfDuration - progress) / halfDuration;
g.drawImage(cardBack, (w - flipWidth) / 2, 0, flipWidth, h);
}
}
}
}

View File

@@ -32,6 +32,7 @@ public class FLabel extends FDisplayObject implements IButton {
private boolean bldSelected = false;
private boolean bldOpaque = false;
private boolean bldIconInBackground = false;
private boolean bldIconScaleWithFont = false;
private boolean bldIconScaleAuto = true;
private boolean bldEnabled = true;
private boolean bldParseSymbols = true;
@@ -60,6 +61,7 @@ public class FLabel extends FDisplayObject implements IButton {
public Builder alphaComposite(final float a0) { this.bldAlphaComposite = a0; return this; }
public Builder enabled(final boolean b0) { this.bldEnabled = b0; return this; }
public Builder iconScaleAuto(final boolean b0) { this.bldIconScaleAuto = b0; return this; }
public Builder iconScaleWithFont(final boolean b0) { this.bldIconScaleWithFont = b0; return this; }
public Builder iconScaleFactor(final float f0) { this.bldIconScaleFactor = f0; return this; }
public Builder iconInBackground(final boolean b0) { this.bldIconInBackground = b0; return this; }
public Builder iconInBackground() { iconInBackground(true); return this; }
@@ -103,7 +105,7 @@ public class FLabel extends FDisplayObject implements IButton {
private float alphaComposite;
private HAlignment alignment;
private Vector2 insets;
private boolean selectable, selected, opaque, iconInBackground, iconScaleAuto, pressed;
private boolean selectable, selected, opaque, iconInBackground, iconScaleAuto, iconScaleWithFont, pressed;
private String text;
private FImage icon;
@@ -123,6 +125,7 @@ public class FLabel extends FDisplayObject implements IButton {
opaque = b0.bldOpaque;
iconInBackground = b0.bldIconInBackground;
iconScaleAuto = b0.bldIconScaleAuto;
iconScaleWithFont = b0.bldIconScaleWithFont;
text = b0.bldText != null ? b0.bldText : "";
icon = b0.bldIcon;
textColor = b0.bldTextColor;
@@ -323,7 +326,11 @@ public class FLabel extends FDisplayObject implements IButton {
float iconHeight = icon.getHeight();
float aspectRatio = iconWidth / iconHeight;
if (iconInBackground || iconScaleAuto) {
if (iconScaleWithFont) {
iconHeight = font.getLineHeight() * iconScaleFactor;
iconWidth = iconHeight * aspectRatio;
}
else if (iconInBackground || iconScaleAuto) {
iconHeight = h * iconScaleFactor;
iconWidth = iconHeight * aspectRatio;
}

View File

@@ -8,6 +8,7 @@ import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.utils.Timer;
import com.badlogic.gdx.utils.Timer.Task;
import forge.FThreads;
import forge.Forge;
import forge.Graphics;
import forge.assets.FSkinColor;
@@ -90,6 +91,8 @@ public abstract class FOverlay extends FContainer {
@Override
public void setVisible(boolean visible0) {
FThreads.assertExecutedByEdt(true); //prevent showing or hiding overlays from background thread
if (this.isVisible() == visible0) { return; }
//ensure task to hide temporary overlay cancelled and run if another overlay becomes shown or hidden

View File

@@ -275,7 +275,7 @@ public class ConquestController {
//also build list of all rewards including replacement shards for each duplicate card
//build this list in reverse order so commons appear first
int shards = 0;
List<ConquestReward> allRewards = new ArrayList<ConquestReward>();
final List<ConquestReward> allRewards = new ArrayList<ConquestReward>();
for (int i = rewards.size() - 1; i >= 0; i--) {
int replacementShards = 0;
PaperCard card = rewards.get(i);
@@ -287,7 +287,12 @@ public class ConquestController {
allRewards.add(new ConquestReward(card, replacementShards));
}
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override
public void run() {
view.showConquestRewards("Booster Awarded", allRewards);
}
});
model.unlockCards(rewards);
model.rewardAEtherShards(shards);
}