mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Improve bug report dialog for mobile game
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1078,6 +1078,7 @@ forge-gui-mobile/src/forge/assets/ImageCache.java -text
|
|||||||
forge-gui-mobile/src/forge/assets/ImageLoader.java -text
|
forge-gui-mobile/src/forge/assets/ImageLoader.java -text
|
||||||
forge-gui-mobile/src/forge/deck/FDeckChooser.java -text
|
forge-gui-mobile/src/forge/deck/FDeckChooser.java -text
|
||||||
forge-gui-mobile/src/forge/deck/FDeckViewer.java -text
|
forge-gui-mobile/src/forge/deck/FDeckViewer.java -text
|
||||||
|
forge-gui-mobile/src/forge/error/BugReportDialog.java -text
|
||||||
forge-gui-mobile/src/forge/itemmanager/CardManager.java -text
|
forge-gui-mobile/src/forge/itemmanager/CardManager.java -text
|
||||||
forge-gui-mobile/src/forge/itemmanager/DeckManager.java -text
|
forge-gui-mobile/src/forge/itemmanager/DeckManager.java -text
|
||||||
forge-gui-mobile/src/forge/itemmanager/ItemManager.java -text
|
forge-gui-mobile/src/forge/itemmanager/ItemManager.java -text
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class BugReportDialog {
|
|||||||
ArrayList<Object> options = new ArrayList<Object>();
|
ArrayList<Object> options = new ArrayList<Object>();
|
||||||
options.add(new JButton(new _CopyAndGo(area)));
|
options.add(new JButton(new _CopyAndGo(area)));
|
||||||
options.add(new JButton(new _SaveAction(area)));
|
options.add(new JButton(new _SaveAction(area)));
|
||||||
options.add("Close");
|
options.add(BugReporter.CONTINUE);
|
||||||
if (showExitAppBtn) {
|
if (showExitAppBtn) {
|
||||||
options.add(new JButton(new _ExitAction()));
|
options.add(new JButton(new _ExitAction()));
|
||||||
}
|
}
|
||||||
@@ -85,8 +85,8 @@ public class BugReportDialog {
|
|||||||
private final JTextArea text;
|
private final JTextArea text;
|
||||||
|
|
||||||
public _CopyAndGo(JTextArea text) {
|
public _CopyAndGo(JTextArea text) {
|
||||||
super("Copy and go to forum");
|
super(BugReporter.REPORT);
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_R, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ public class BugReportDialog {
|
|||||||
private final JTextArea area;
|
private final JTextArea area;
|
||||||
|
|
||||||
public _SaveAction(final JTextArea areaParam) {
|
public _SaveAction(final JTextArea areaParam) {
|
||||||
super("Save to file");
|
super(BugReporter.SAVE);
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||||
this.area = areaParam;
|
this.area = areaParam;
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ public class BugReportDialog {
|
|||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
private static class _ExitAction extends AbstractAction {
|
private static class _ExitAction extends AbstractAction {
|
||||||
public _ExitAction() {
|
public _ExitAction() {
|
||||||
super("Exit application");
|
super(BugReporter.EXIT);
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import forge.assets.FTextureImage;
|
|||||||
import forge.assets.ISkinImage;
|
import forge.assets.ISkinImage;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.FDeckViewer;
|
import forge.deck.FDeckViewer;
|
||||||
|
import forge.error.BugReportDialog;
|
||||||
import forge.events.UiEvent;
|
import forge.events.UiEvent;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
@@ -151,7 +152,7 @@ public class GuiMobile implements IGuiBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showBugReportDialog(String title, String text, boolean showExitAppBtn) {
|
public void showBugReportDialog(String title, String text, boolean showExitAppBtn) {
|
||||||
FOptionPane.showErrorDialog(text, title); //TODO: Create dialog with bells and whistles of desktop bug report dialog
|
BugReportDialog.show(title, text, showExitAppBtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
100
forge-gui-mobile/src/forge/error/BugReportDialog.java
Normal file
100
forge-gui-mobile/src/forge/error/BugReportDialog.java
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
package forge.error;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
|
||||||
|
|
||||||
|
import forge.Forge;
|
||||||
|
import forge.Forge.Graphics;
|
||||||
|
import forge.assets.FSkinColor;
|
||||||
|
import forge.assets.FSkinFont;
|
||||||
|
import forge.assets.FSkinColor.Colors;
|
||||||
|
import forge.toolbox.FOptionPane;
|
||||||
|
import forge.toolbox.FScrollPane;
|
||||||
|
import forge.util.Callback;
|
||||||
|
|
||||||
|
public class BugReportDialog extends FOptionPane {
|
||||||
|
private static boolean dialogShown;
|
||||||
|
|
||||||
|
public static void show(String title, String text, boolean showExitAppBtn) {
|
||||||
|
if (dialogShown) { return; }
|
||||||
|
|
||||||
|
dialogShown = true;
|
||||||
|
BugReportDialog dialog = new BugReportDialog(title, text, showExitAppBtn);
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
private BugReportDialog(String title, String text0, boolean showExitAppBtn) {
|
||||||
|
super(BugReporter.HELP_TEXT + "\n\n" + BugReporter.HELP_URL_LABEL + " " + BugReporter.HELP_URL + ".",
|
||||||
|
title, null, new TemplateView(text0),
|
||||||
|
getOptions(showExitAppBtn), 0, null);
|
||||||
|
text = text0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onButtonClick(final int option, final Callback<Integer> callback) {
|
||||||
|
switch (option) {
|
||||||
|
case 0:
|
||||||
|
BugReporter.copyAndGoToForums(text);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
BugReporter.saveToFile(text);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
hide();
|
||||||
|
dialogShown = false;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
hide();
|
||||||
|
Gdx.app.exit();
|
||||||
|
dialogShown = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] getOptions(boolean showExitAppBtn) {
|
||||||
|
String[] options = new String[showExitAppBtn ? 4 : 3];
|
||||||
|
options[0] = BugReporter.REPORT;
|
||||||
|
options[1] = BugReporter.SAVE;
|
||||||
|
options[2] = BugReporter.CONTINUE;
|
||||||
|
if (showExitAppBtn) {
|
||||||
|
options[3] = BugReporter.EXIT;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TemplateView extends FScrollPane {
|
||||||
|
private static final FSkinFont FONT = FSkinFont.get(11);
|
||||||
|
private static final FSkinColor BACK_COLOR = FSkinColor.get(Colors.CLR_ZEBRA);
|
||||||
|
private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT);
|
||||||
|
private static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS);
|
||||||
|
private static final float PADDING = 3;
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
private TemplateView(String text0) {
|
||||||
|
text = text0;
|
||||||
|
setHeight(Forge.getCurrentScreen().getHeight() / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) {
|
||||||
|
TextBounds bounds = FONT.getFont().getMultiLineBounds(text);
|
||||||
|
return new ScrollBounds(bounds.width + 2 * PADDING, bounds.height + 2 * PADDING +
|
||||||
|
FONT.getFont().getLineHeight() - FONT.getFont().getCapHeight()); //account for height below baseline of final line);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawBackground(Graphics g) {
|
||||||
|
g.fillRect(BACK_COLOR, 0, 0, getWidth(), getHeight());
|
||||||
|
g.drawText(text, FONT, FORE_COLOR, PADDING - getScrollLeft(), PADDING - getScrollTop(), getScrollWidth() - 2 * PADDING, getScrollHeight() - 2 * PADDING, false, HAlignment.LEFT, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawOverlay(Graphics g) {
|
||||||
|
g.drawRect(1, BORDER_COLOR, 0, 0, getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ import forge.toolbox.FEvent.FEventType;
|
|||||||
public class FButton extends FDisplayObject implements IButton {
|
public class FButton extends FDisplayObject implements IButton {
|
||||||
private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT);
|
private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT);
|
||||||
private static final float DISABLED_COMPOSITE = 0.25f;
|
private static final float DISABLED_COMPOSITE = 0.25f;
|
||||||
private static final float PADDING = 3;
|
private static final float PADDING = 10;
|
||||||
|
|
||||||
private FSkinImage imgL, imgM, imgR;
|
private FSkinImage imgL, imgM, imgR;
|
||||||
private String text;
|
private String text;
|
||||||
@@ -123,7 +123,7 @@ public class FButton extends FDisplayObject implements IButton {
|
|||||||
public TextBounds getAutoSizeBounds() {
|
public TextBounds getAutoSizeBounds() {
|
||||||
TextBounds bounds = new TextBounds();
|
TextBounds bounds = new TextBounds();
|
||||||
bounds.width = font.getFont().getBounds(text).width + 2 * PADDING;
|
bounds.width = font.getFont().getBounds(text).width + 2 * PADDING;
|
||||||
bounds.height = font.getFont().getCapHeight();
|
bounds.height = 3 * font.getFont().getCapHeight();
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public abstract class FDialog extends FOverlay {
|
|||||||
private static final FSkinColor TITLE_BACK_COLOR = FSkinColor.get(Colors.CLR_THEME2);
|
private static final FSkinColor TITLE_BACK_COLOR = FSkinColor.get(Colors.CLR_THEME2);
|
||||||
private static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS);
|
private static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS);
|
||||||
private static final float TITLE_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.6f);
|
private static final float TITLE_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.6f);
|
||||||
private static float INSET_X = 10;
|
private static float INSETS = 10;
|
||||||
|
|
||||||
private FLabel lblTitlebar;
|
private FLabel lblTitlebar;
|
||||||
private float totalHeight;
|
private float totalHeight;
|
||||||
@@ -25,20 +25,19 @@ public abstract class FDialog extends FOverlay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void doLayout(float width, float height) {
|
protected final void doLayout(float width, float height) {
|
||||||
width -= 2 * INSET_X;
|
width -= 2 * INSETS;
|
||||||
|
|
||||||
//ensure no more than half the screen is covered by dialog so it can be moved to see anything
|
float contentHeight = layoutAndGetHeight(width, height - TITLE_HEIGHT - 2 * INSETS);
|
||||||
float contentHeight = layoutAndGetHeight(width, height / 2 - TITLE_HEIGHT);
|
|
||||||
totalHeight = contentHeight + TITLE_HEIGHT;
|
totalHeight = contentHeight + TITLE_HEIGHT;
|
||||||
float y = (height - totalHeight) / 2;
|
float y = (height - totalHeight) / 2;
|
||||||
|
|
||||||
lblTitlebar.setBounds(INSET_X, y, width, TITLE_HEIGHT);
|
lblTitlebar.setBounds(INSETS, y, width, TITLE_HEIGHT);
|
||||||
|
|
||||||
//shift all children into position below titlebar
|
//shift all children into position below titlebar
|
||||||
float dy = lblTitlebar.getBottom();
|
float dy = lblTitlebar.getBottom();
|
||||||
for (FDisplayObject child : getChildren()) {
|
for (FDisplayObject child : getChildren()) {
|
||||||
if (child != lblTitlebar) {
|
if (child != lblTitlebar) {
|
||||||
child.setLeft(child.getLeft() + INSET_X);
|
child.setLeft(child.getLeft() + INSETS);
|
||||||
child.setTop(child.getTop() + dy);
|
child.setTop(child.getTop() + dy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +49,7 @@ public abstract class FDialog extends FOverlay {
|
|||||||
protected void drawBackground(Graphics g) {
|
protected void drawBackground(Graphics g) {
|
||||||
super.drawBackground(g);
|
super.drawBackground(g);
|
||||||
|
|
||||||
float x = INSET_X;
|
float x = INSETS;
|
||||||
float y = lblTitlebar.getTop();
|
float y = lblTitlebar.getTop();
|
||||||
float w = getWidth() - 2 * x;
|
float w = getWidth() - 2 * x;
|
||||||
float h = totalHeight;
|
float h = totalHeight;
|
||||||
@@ -63,7 +62,7 @@ public abstract class FDialog extends FOverlay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void drawOverlay(Graphics g) {
|
protected void drawOverlay(Graphics g) {
|
||||||
float x = INSET_X;
|
float x = INSETS;
|
||||||
float y = lblTitlebar.getTop();
|
float y = lblTitlebar.getTop();
|
||||||
float w = getWidth() - 2 * x;
|
float w = getWidth() - 2 * x;
|
||||||
float h = totalHeight;
|
float h = totalHeight;
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public class FOptionPane extends FDialog {
|
|||||||
|
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
prompt = add(new FTextArea(message));
|
prompt = add(new FTextArea(message));
|
||||||
prompt.setFontSize(14);
|
prompt.setFontSize(12);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prompt = null;
|
prompt = null;
|
||||||
@@ -151,15 +151,19 @@ public class FOptionPane extends FDialog {
|
|||||||
buttons[i] = add(new FButton(options[i], new FEventHandler() {
|
buttons[i] = add(new FButton(options[i], new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
hide();
|
onButtonClick(option, callback);
|
||||||
if (callback != null) {
|
|
||||||
callback.run(option);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onButtonClick(final int option, final Callback<Integer> callback) {
|
||||||
|
hide();
|
||||||
|
if (callback != null) {
|
||||||
|
callback.run(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isButtonEnabled(int index) {
|
public boolean isButtonEnabled(int index) {
|
||||||
return buttons[index].isEnabled();
|
return buttons[index].isEnabled();
|
||||||
}
|
}
|
||||||
@@ -205,7 +209,7 @@ public class FOptionPane extends FDialog {
|
|||||||
y += promptHeight + gapBottom;
|
y += promptHeight + gapBottom;
|
||||||
if (displayObj != null) {
|
if (displayObj != null) {
|
||||||
displayObj.setBounds(x, y, width - 2 * x, displayObj.getHeight());
|
displayObj.setBounds(x, y, width - 2 * x, displayObj.getHeight());
|
||||||
y += gapBottom;
|
y += displayObj.getHeight() + gapBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
//determine size for and position buttons
|
//determine size for and position buttons
|
||||||
@@ -216,7 +220,7 @@ public class FOptionPane extends FDialog {
|
|||||||
maxButtonWidth = buttonWidth;
|
maxButtonWidth = buttonWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float gapBetween = 3;
|
float gapBetween = -2; //use negative so buttons closer together
|
||||||
float buttonWidth = Math.max(maxButtonWidth, 120); //account for margins and enforce minimum width
|
float buttonWidth = Math.max(maxButtonWidth, 120); //account for margins and enforce minimum width
|
||||||
float dx = buttonWidth + gapBetween;
|
float dx = buttonWidth + gapBetween;
|
||||||
float totalButtonWidth = dx * buttons.length - gapBetween;
|
float totalButtonWidth = dx * buttons.length - gapBetween;
|
||||||
|
|||||||
@@ -41,10 +41,15 @@ import java.util.Map.Entry;
|
|||||||
public class BugReporter {
|
public class BugReporter {
|
||||||
private static final int STACK_OVERFLOW_MAX_MESSAGE_LEN = 16 * 1024;
|
private static final int STACK_OVERFLOW_MAX_MESSAGE_LEN = 16 * 1024;
|
||||||
|
|
||||||
|
public static final String REPORT = "Report";
|
||||||
|
public static final String SAVE = "Save";
|
||||||
|
public static final String CONTINUE = "Continue";
|
||||||
|
public static final String EXIT = "Exit";
|
||||||
|
|
||||||
public static final String HELP_TEXT =
|
public static final String HELP_TEXT =
|
||||||
"<html>A template for a post in the bug reports forum topic is shown below. Just select 'Copy and go to forum' "
|
"A template for a post in the bug reports forum topic is shown below. Just select '" + REPORT + "' "
|
||||||
+ "and the template will be copied to your system clipboard and the forum page will open in your browser. "
|
+ "and the template will be copied to your system clipboard and the forum page will open in your browser. "
|
||||||
+ "Then all you have to do is paste the text into a forum post and edit the description line.</html>";
|
+ "Then all you have to do is paste the text into a forum post and edit the description line.";
|
||||||
public static final String HELP_URL_LABEL =
|
public static final String HELP_URL_LABEL =
|
||||||
"Reporting bugs in Forge is very important. We sincerely thank you for your time."
|
"Reporting bugs in Forge is very important. We sincerely thank you for your time."
|
||||||
+ " For help writing a solid bug report, please see:";
|
+ " For help writing a solid bug report, please see:";
|
||||||
|
|||||||
Reference in New Issue
Block a user