Small fixes and additions
- Added: Bulk Marking via Defining an area. - Changed: Moved the Application Starter to a dedicated class - Fixed a bug introduced by Meduris
This commit is contained in:
parent
f7f5b1dc74
commit
525071fca4
@ -4,7 +4,7 @@ plugins {
|
|||||||
|
|
||||||
archivesBaseName = "Mario Kart World Tracker"
|
archivesBaseName = "Mario Kart World Tracker"
|
||||||
version = '1.0.1'
|
version = '1.0.1'
|
||||||
var mainClassName = 'speiger.src.ui.MapPanel'
|
var mainClassName = 'speiger.src.MarioKartWorldTracker'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
210
src/main/java/speiger/src/MarioKartWorldTracker.java
Normal file
210
src/main/java/speiger/src/MarioKartWorldTracker.java
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
package speiger.src;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Checkbox;
|
||||||
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.ItemListener;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
|
import speiger.src.data.CollectableType;
|
||||||
|
import speiger.src.data.Registry;
|
||||||
|
import speiger.src.ui.DownloadTask;
|
||||||
|
import speiger.src.ui.MapPanel;
|
||||||
|
import speiger.src.ui.VerticalFlowLayout;
|
||||||
|
|
||||||
|
public class MarioKartWorldTracker {
|
||||||
|
private static final JFileChooser CHOOSER = new JFileChooser(new File(Preferences.userRoot().node(MapPanel.class.getName()).get("Last Folder", new File(".").getAbsolutePath())));
|
||||||
|
private static Checkbox P_SWITCH;
|
||||||
|
private static Checkbox MEDALS;
|
||||||
|
private static Checkbox PANEL;
|
||||||
|
private static Checkbox CHUCKS;
|
||||||
|
|
||||||
|
public static void main(String...args) {
|
||||||
|
Toolkit.getDefaultToolkit().setDynamicLayout(false);
|
||||||
|
JFrame frame = new JFrame();
|
||||||
|
frame.setIconImage(new ImageIcon(MapPanel.class.getResource("/assets/images/icon.png")).getImage());
|
||||||
|
frame.setLayout(new BorderLayout());
|
||||||
|
frame.setBounds(0, 0, 800, 600);
|
||||||
|
frame.setTitle("Mario Kart World Progress Tracker");
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.setLocationRelativeTo(null);
|
||||||
|
MapPanel panel = new MapPanel(frame);
|
||||||
|
frame.add(panel, BorderLayout.CENTER);
|
||||||
|
JMenuBar bar = new JMenuBar();
|
||||||
|
frame.setJMenuBar(bar);
|
||||||
|
JMenu menu = bar.add(new JMenu("File"));
|
||||||
|
menu.add(item("Import Save", T -> {
|
||||||
|
Preferences prefs = Preferences.userRoot().node(MapPanel.class.getName());
|
||||||
|
if(CHOOSER.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File file = CHOOSER.getSelectedFile();
|
||||||
|
if(!file.getName().endsWith(".json")) return;
|
||||||
|
try(BufferedReader reader = Files.newBufferedReader(file.toPath())) {
|
||||||
|
List<UUID> ids = new ArrayList<>();
|
||||||
|
for(JsonElement element : JsonParser.parseReader(reader).getAsJsonObject().getAsJsonArray("completed")) {
|
||||||
|
ids.add(UUID.fromString(element.getAsString()));
|
||||||
|
}
|
||||||
|
Registry.INSTANCE.importSave(ids);
|
||||||
|
panel.onImported();
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
JOptionPane.showMessageDialog(frame, "Importing caused an error \n"+e.toString(), "Importing Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.put("Last Folder", file.getParent());
|
||||||
|
}
|
||||||
|
}, null));
|
||||||
|
menu.add(item("Export Save", T -> {
|
||||||
|
Preferences prefs = Preferences.userRoot().node(MapPanel.class.getName());
|
||||||
|
if(CHOOSER.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File file = CHOOSER.getSelectedFile();
|
||||||
|
String name = file.getName();
|
||||||
|
int index = name.lastIndexOf(".");
|
||||||
|
if(index > -1) name = name.substring(0, index);
|
||||||
|
name += ".json";
|
||||||
|
Path save = Registry.getOrigin().resolve("data/save.json");
|
||||||
|
if(Files.notExists(save)) return;
|
||||||
|
|
||||||
|
try { Files.copy(save, file.toPath().getParent().resolve(name), StandardCopyOption.REPLACE_EXISTING); }
|
||||||
|
catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
JOptionPane.showMessageDialog(frame, "Exporting caused an error \n"+e.toString(), "Exporting Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.put("Last Folder", file.getParent());
|
||||||
|
|
||||||
|
}
|
||||||
|
}, null));
|
||||||
|
menu.add(item("Download all Previews", T -> {
|
||||||
|
if(JOptionPane.showConfirmDialog(frame, "Are you sure you want to download all missing images?", "Download Images", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||||
|
new DownloadTask(frame);
|
||||||
|
}
|
||||||
|
}, null));
|
||||||
|
menu.add(item("Credits", T -> {
|
||||||
|
JOptionPane.showMessageDialog(frame, "Credits Go to:\nhttps://mkw.techtangents.net and\nhttps://www.gamerguides.com/mario-kart-world/maps/world \nwhich are used as Resource Providers", "Credits", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}, null));
|
||||||
|
|
||||||
|
JMenu controls = new JMenu("Controls");
|
||||||
|
controls.add("Left Button: Toggle Completion/Finish Bulk Action");
|
||||||
|
controls.add("Right Button: Show Location");
|
||||||
|
controls.add("Left Button Dragging: Move Map");
|
||||||
|
controls.add("Mouse Scrolling: Zoom");
|
||||||
|
controls.add("Press 'm' when mouse is on map to start bulk action");
|
||||||
|
|
||||||
|
|
||||||
|
JMenu bulk = new JMenu("Bulk Actions");
|
||||||
|
bulk.add(item("Complete Visible", T -> {
|
||||||
|
panel.setCompletionState(true);
|
||||||
|
}, null));
|
||||||
|
bulk.add(item("Uncomplete Visible", T -> {
|
||||||
|
panel.setCompletionState(false);
|
||||||
|
}, null));
|
||||||
|
bulk.add(item("Bulk Mark", T -> {
|
||||||
|
panel.startBulkMarking(panel.getMousePosition());
|
||||||
|
}, KeyStroke.getKeyStroke('m')));
|
||||||
|
bar.add(bulk);
|
||||||
|
JMenu fuckups = new JMenu("I Fucked up");
|
||||||
|
fuckups.add(item("Reset Zoom", T -> {
|
||||||
|
panel.resetZoom();
|
||||||
|
}, KeyStroke.getKeyStroke('z')));
|
||||||
|
fuckups.add(item("Reset Offset", T -> {
|
||||||
|
panel.resetMap();
|
||||||
|
}, KeyStroke.getKeyStroke('r')));
|
||||||
|
|
||||||
|
bar.add(fuckups);
|
||||||
|
bar.add(controls);
|
||||||
|
|
||||||
|
JPanel sideMenu = new JPanel();
|
||||||
|
sideMenu.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 5, 0));
|
||||||
|
|
||||||
|
sideMenu.add(new JLabel("Filter"));
|
||||||
|
P_SWITCH = (Checkbox)sideMenu.add(box("P-Switches", T -> onFilterChanged(panel::updateFilter)));
|
||||||
|
MEDALS = (Checkbox)sideMenu.add(box("Medals", T -> onFilterChanged(panel::updateFilter)));
|
||||||
|
PANEL = (Checkbox)sideMenu.add(box("Panels", T -> onFilterChanged(panel::updateFilter)));
|
||||||
|
CHUCKS = (Checkbox)sideMenu.add(box("Chucks", T -> onFilterChanged(panel::updateFilter)));
|
||||||
|
JLabel PSwitchProgress = new JLabel(Registry.INSTANCE.completed(CollectableType.PSWITCH)+" / "+Registry.INSTANCE.total(CollectableType.PSWITCH));
|
||||||
|
JLabel MedalsProgress = new JLabel(Registry.INSTANCE.completed(CollectableType.MEDAL)+" / "+Registry.INSTANCE.total(CollectableType.MEDAL));
|
||||||
|
JLabel PanelProgress = new JLabel(Registry.INSTANCE.completed(CollectableType.PANEL)+" / "+Registry.INSTANCE.total(CollectableType.PANEL));
|
||||||
|
JLabel ChucksProgress = new JLabel(Registry.INSTANCE.completed(CollectableType.CHUCKS)+" / "+Registry.INSTANCE.total(CollectableType.CHUCKS));
|
||||||
|
panel.setProgressListener(() -> {
|
||||||
|
PSwitchProgress.setText(Registry.INSTANCE.completed(CollectableType.PSWITCH)+" / "+Registry.INSTANCE.total(CollectableType.PSWITCH));
|
||||||
|
MedalsProgress.setText(Registry.INSTANCE.completed(CollectableType.MEDAL)+" / "+Registry.INSTANCE.total(CollectableType.MEDAL));
|
||||||
|
PanelProgress.setText(Registry.INSTANCE.completed(CollectableType.PANEL)+" / "+Registry.INSTANCE.total(CollectableType.PANEL));
|
||||||
|
ChucksProgress.setText(Registry.INSTANCE.completed(CollectableType.CHUCKS)+" / "+Registry.INSTANCE.total(CollectableType.CHUCKS));
|
||||||
|
EventQueue.invokeLater(sideMenu::repaint);
|
||||||
|
});
|
||||||
|
|
||||||
|
sideMenu.add(new JLabel("P-Switches:"));
|
||||||
|
sideMenu.add(PSwitchProgress);
|
||||||
|
sideMenu.add(new JLabel("Medals:"));
|
||||||
|
sideMenu.add(MedalsProgress);
|
||||||
|
sideMenu.add(new JLabel("Panels:"));
|
||||||
|
sideMenu.add(PanelProgress);
|
||||||
|
sideMenu.add(new JLabel("Chucks:"));
|
||||||
|
sideMenu.add(ChucksProgress);
|
||||||
|
|
||||||
|
frame.add(sideMenu, BorderLayout.WEST);
|
||||||
|
|
||||||
|
panel.resetMap();
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
Registry.INSTANCE.processQueue();
|
||||||
|
Thread.sleep(Duration.ofMillis(50));
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Checkbox box(String name, ItemListener listener) {
|
||||||
|
Checkbox box = new Checkbox(name, true);
|
||||||
|
box.addItemListener(listener);
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void onFilterChanged(Consumer<EnumSet<CollectableType>> consumer) {
|
||||||
|
EnumSet<CollectableType> types = EnumSet.noneOf(CollectableType.class);
|
||||||
|
if(P_SWITCH.getState()) types.add(CollectableType.PSWITCH);
|
||||||
|
if(MEDALS.getState()) types.add(CollectableType.MEDAL);
|
||||||
|
if(PANEL.getState()) types.add(CollectableType.PANEL);
|
||||||
|
if(CHUCKS.getState()) types.add(CollectableType.CHUCKS);
|
||||||
|
consumer.accept(types);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JMenuItem item(String name, ActionListener action, KeyStroke stroke) {
|
||||||
|
JMenuItem item = new JMenuItem(name);
|
||||||
|
item.addActionListener(action);
|
||||||
|
item.setAccelerator(stroke);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
@ -203,12 +203,12 @@ public class Registry {
|
|||||||
|
|
||||||
public void markComplete(UUID id) {
|
public void markComplete(UUID id) {
|
||||||
completed.add(id);
|
completed.add(id);
|
||||||
if (bulkOperationActive) save();
|
if (!bulkOperationActive) save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unmarkComplete(UUID id) {
|
public void unmarkComplete(UUID id) {
|
||||||
completed.remove(id);
|
completed.remove(id);
|
||||||
if (bulkOperationActive) save();
|
if (!bulkOperationActive) save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBulkOperation(boolean bulk) {
|
public void setBulkOperation(boolean bulk) {
|
||||||
|
@ -1,64 +1,39 @@
|
|||||||
package speiger.src.ui;
|
package speiger.src.ui;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.Color;
|
||||||
import java.awt.Checkbox;
|
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.RenderingHints;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.ItemListener;
|
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseWheelEvent;
|
import java.awt.event.MouseWheelEvent;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.prefs.Preferences;
|
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JFileChooser;
|
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JMenu;
|
|
||||||
import javax.swing.JMenuBar;
|
|
||||||
import javax.swing.JMenuItem;
|
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.KeyStroke;
|
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
import speiger.src.data.Collectable;
|
import speiger.src.data.Collectable;
|
||||||
import speiger.src.data.CollectableType;
|
import speiger.src.data.CollectableType;
|
||||||
import speiger.src.data.Registry;
|
import speiger.src.data.Registry;
|
||||||
|
|
||||||
public class MapPanel extends JPanel {
|
public class MapPanel extends JPanel {
|
||||||
private static final JFileChooser CHOOSER = new JFileChooser(new File(Preferences.userRoot().node(MapPanel.class.getName()).get("Last Folder", new File(".").getAbsolutePath())));
|
|
||||||
private static final long serialVersionUID = 7639401429824622357L;
|
private static final long serialVersionUID = 7639401429824622357L;
|
||||||
private static Checkbox P_SWITCH;
|
|
||||||
private static Checkbox MEDALS;
|
|
||||||
private static Checkbox PANEL;
|
|
||||||
private static Checkbox CHUCKS;
|
|
||||||
|
|
||||||
JFrame owner;
|
JFrame owner;
|
||||||
Runnable progressUpdate;
|
Runnable progressUpdate;
|
||||||
float zoom = 1F;
|
float zoom = 1F;
|
||||||
Point offset = new Point(-568, -271);
|
Point offset = new Point(-568, -271);
|
||||||
Point lastDrag = null;
|
Point lastDrag = null;
|
||||||
|
Point startPos;
|
||||||
|
Point lastPos;
|
||||||
Image map = new ImageIcon(MapPanel.class.getResource("/assets/images/map.png")).getImage();
|
Image map = new ImageIcon(MapPanel.class.getResource("/assets/images/map.png")).getImage();
|
||||||
Image[] medal = new Image[] {
|
Image[] medal = new Image[] {
|
||||||
new ImageIcon(MapPanel.class.getResource("/assets/images/medal.png")).getImage(),
|
new ImageIcon(MapPanel.class.getResource("/assets/images/medal.png")).getImage(),
|
||||||
@ -80,163 +55,6 @@ public class MapPanel extends JPanel {
|
|||||||
List<Marker> visibleMarkers = new ArrayList<Marker>();
|
List<Marker> visibleMarkers = new ArrayList<Marker>();
|
||||||
Marker lastMarker = null;
|
Marker lastMarker = null;
|
||||||
|
|
||||||
public static void main(String...args) {
|
|
||||||
Toolkit.getDefaultToolkit().setDynamicLayout(false);
|
|
||||||
JFrame frame = new JFrame();
|
|
||||||
frame.setIconImage(new ImageIcon(MapPanel.class.getResource("/assets/images/icon.png")).getImage());
|
|
||||||
frame.setLayout(new BorderLayout());
|
|
||||||
frame.setBounds(0, 0, 800, 600);
|
|
||||||
frame.setTitle("Mario Kart World Progress Tracker");
|
|
||||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
frame.setLocationRelativeTo(null);
|
|
||||||
MapPanel panel = new MapPanel(frame);
|
|
||||||
frame.add(panel, BorderLayout.CENTER);
|
|
||||||
JMenuBar bar = new JMenuBar();
|
|
||||||
frame.setJMenuBar(bar);
|
|
||||||
JMenu menu = bar.add(new JMenu("File"));
|
|
||||||
menu.add(item("Import Save", T -> {
|
|
||||||
Preferences prefs = Preferences.userRoot().node(MapPanel.class.getName());
|
|
||||||
if(CHOOSER.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
|
|
||||||
File file = CHOOSER.getSelectedFile();
|
|
||||||
if(!file.getName().endsWith(".json")) return;
|
|
||||||
try(BufferedReader reader = Files.newBufferedReader(file.toPath())) {
|
|
||||||
List<UUID> ids = new ArrayList<>();
|
|
||||||
for(JsonElement element : JsonParser.parseReader(reader).getAsJsonObject().getAsJsonArray("completed")) {
|
|
||||||
ids.add(UUID.fromString(element.getAsString()));
|
|
||||||
}
|
|
||||||
Registry.INSTANCE.importSave(ids);
|
|
||||||
panel.onImported();
|
|
||||||
}
|
|
||||||
catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
JOptionPane.showMessageDialog(frame, "Importing caused an error \n"+e.toString(), "Importing Error", JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
prefs.put("Last Folder", file.getParent());
|
|
||||||
}
|
|
||||||
}, null));
|
|
||||||
menu.add(item("Export Save", T -> {
|
|
||||||
Preferences prefs = Preferences.userRoot().node(MapPanel.class.getName());
|
|
||||||
if(CHOOSER.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
|
|
||||||
File file = CHOOSER.getSelectedFile();
|
|
||||||
String name = file.getName();
|
|
||||||
int index = name.lastIndexOf(".");
|
|
||||||
if(index > -1) name = name.substring(0, index);
|
|
||||||
name += ".json";
|
|
||||||
Path save = Registry.getOrigin().resolve("data/save.json");
|
|
||||||
if(Files.notExists(save)) return;
|
|
||||||
|
|
||||||
try { Files.copy(save, file.toPath().getParent().resolve(name), StandardCopyOption.REPLACE_EXISTING); }
|
|
||||||
catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
JOptionPane.showMessageDialog(frame, "Exporting caused an error \n"+e.toString(), "Exporting Error", JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
prefs.put("Last Folder", file.getParent());
|
|
||||||
|
|
||||||
}
|
|
||||||
}, null));
|
|
||||||
menu.add(item("Download all Previews", T -> {
|
|
||||||
if(JOptionPane.showConfirmDialog(frame, "Are you sure you want to download all missing images?", "Download Images", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
|
|
||||||
new DownloadTask(frame);
|
|
||||||
}
|
|
||||||
}, null));
|
|
||||||
menu.add(item("Credits", T -> {
|
|
||||||
JOptionPane.showMessageDialog(frame, "Credits Go to:\nhttps://mkw.techtangents.net and\nhttps://www.gamerguides.com/mario-kart-world/maps/world \nwhich are used as Resource Providers", "Credits", JOptionPane.INFORMATION_MESSAGE);
|
|
||||||
}, null));
|
|
||||||
|
|
||||||
JMenu controls = new JMenu("Controls");
|
|
||||||
controls.add("Left Button: Toggle Completion");
|
|
||||||
controls.add("Right Button: Show Location");
|
|
||||||
controls.add("Left Button Dragging: Move Map");
|
|
||||||
controls.add("Mouse Scrolling: Zoom");
|
|
||||||
|
|
||||||
|
|
||||||
JMenu bulk = new JMenu("Bulk Actions");
|
|
||||||
bulk.add(item("Complete Visible", T -> {
|
|
||||||
panel.setCompletionState(true);
|
|
||||||
}, null));
|
|
||||||
bulk.add(item("Uncomplete Visible", T -> {
|
|
||||||
panel.setCompletionState(false);
|
|
||||||
}, null));
|
|
||||||
bar.add(bulk);
|
|
||||||
JMenu fuckups = new JMenu("I Fucked up");
|
|
||||||
fuckups.add(item("Reset Zoom", T -> {
|
|
||||||
panel.resetZoom();
|
|
||||||
}, KeyStroke.getKeyStroke('z')));
|
|
||||||
fuckups.add(item("Reset Offset", T -> {
|
|
||||||
panel.resetMap();
|
|
||||||
}, KeyStroke.getKeyStroke('r')));
|
|
||||||
|
|
||||||
bar.add(fuckups);
|
|
||||||
bar.add(controls);
|
|
||||||
|
|
||||||
JPanel sideMenu = new JPanel();
|
|
||||||
sideMenu.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 5, 0));
|
|
||||||
|
|
||||||
sideMenu.add(new JLabel("Filter"));
|
|
||||||
P_SWITCH = (Checkbox)sideMenu.add(box("P-Switches", T -> onFilterChanged(panel::updateFilter)));
|
|
||||||
MEDALS = (Checkbox)sideMenu.add(box("Medals", T -> onFilterChanged(panel::updateFilter)));
|
|
||||||
PANEL = (Checkbox)sideMenu.add(box("Panels", T -> onFilterChanged(panel::updateFilter)));
|
|
||||||
CHUCKS = (Checkbox)sideMenu.add(box("Chucks", T -> onFilterChanged(panel::updateFilter)));
|
|
||||||
JLabel PSwitchProgress = new JLabel(Registry.INSTANCE.completed(CollectableType.PSWITCH)+" / "+Registry.INSTANCE.total(CollectableType.PSWITCH));
|
|
||||||
JLabel MedalsProgress = new JLabel(Registry.INSTANCE.completed(CollectableType.MEDAL)+" / "+Registry.INSTANCE.total(CollectableType.MEDAL));
|
|
||||||
JLabel PanelProgress = new JLabel(Registry.INSTANCE.completed(CollectableType.PANEL)+" / "+Registry.INSTANCE.total(CollectableType.PANEL));
|
|
||||||
JLabel ChucksProgress = new JLabel(Registry.INSTANCE.completed(CollectableType.CHUCKS)+" / "+Registry.INSTANCE.total(CollectableType.CHUCKS));
|
|
||||||
panel.progressUpdate = () -> {
|
|
||||||
PSwitchProgress.setText(Registry.INSTANCE.completed(CollectableType.PSWITCH)+" / "+Registry.INSTANCE.total(CollectableType.PSWITCH));
|
|
||||||
MedalsProgress.setText(Registry.INSTANCE.completed(CollectableType.MEDAL)+" / "+Registry.INSTANCE.total(CollectableType.MEDAL));
|
|
||||||
PanelProgress.setText(Registry.INSTANCE.completed(CollectableType.PANEL)+" / "+Registry.INSTANCE.total(CollectableType.PANEL));
|
|
||||||
ChucksProgress.setText(Registry.INSTANCE.completed(CollectableType.CHUCKS)+" / "+Registry.INSTANCE.total(CollectableType.CHUCKS));
|
|
||||||
EventQueue.invokeLater(sideMenu::repaint);
|
|
||||||
};
|
|
||||||
|
|
||||||
sideMenu.add(new JLabel("P-Switches:"));
|
|
||||||
sideMenu.add(PSwitchProgress);
|
|
||||||
sideMenu.add(new JLabel("Medals:"));
|
|
||||||
sideMenu.add(MedalsProgress);
|
|
||||||
sideMenu.add(new JLabel("Panels:"));
|
|
||||||
sideMenu.add(PanelProgress);
|
|
||||||
sideMenu.add(new JLabel("Chucks:"));
|
|
||||||
sideMenu.add(ChucksProgress);
|
|
||||||
|
|
||||||
frame.add(sideMenu, BorderLayout.WEST);
|
|
||||||
|
|
||||||
panel.resetMap();
|
|
||||||
frame.setVisible(true);
|
|
||||||
|
|
||||||
while(true) {
|
|
||||||
try {
|
|
||||||
Registry.INSTANCE.processQueue();
|
|
||||||
Thread.sleep(Duration.ofMillis(50));
|
|
||||||
}
|
|
||||||
catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Checkbox box(String name, ItemListener listener) {
|
|
||||||
Checkbox box = new Checkbox(name, true);
|
|
||||||
box.addItemListener(listener);
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void onFilterChanged(Consumer<EnumSet<CollectableType>> consumer) {
|
|
||||||
EnumSet<CollectableType> types = EnumSet.noneOf(CollectableType.class);
|
|
||||||
if(P_SWITCH.getState()) types.add(CollectableType.PSWITCH);
|
|
||||||
if(MEDALS.getState()) types.add(CollectableType.MEDAL);
|
|
||||||
if(PANEL.getState()) types.add(CollectableType.PANEL);
|
|
||||||
if(CHUCKS.getState()) types.add(CollectableType.CHUCKS);
|
|
||||||
consumer.accept(types);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JMenuItem item(String name, ActionListener action, KeyStroke stroke) {
|
|
||||||
JMenuItem item = new JMenuItem(name);
|
|
||||||
item.addActionListener(action);
|
|
||||||
item.setAccelerator(stroke);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Image[] fromType(CollectableType type) {
|
private Image[] fromType(CollectableType type) {
|
||||||
return switch(type) {
|
return switch(type) {
|
||||||
@ -275,8 +93,9 @@ public class MapPanel extends JPanel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseMoved(MouseEvent e) {
|
public void mouseMoved(MouseEvent e) {
|
||||||
Point hover = screenToMap(e.getPoint());
|
lastPos = screenToMap(e.getPoint());
|
||||||
Marker marker = findMarker(hover, zoom);
|
if(startPos != null) repaint();
|
||||||
|
Marker marker = findMarker(lastPos, zoom);
|
||||||
if(marker == lastMarker) return;
|
if(marker == lastMarker) return;
|
||||||
if(lastMarker != null) lastMarker.setHovered(false);
|
if(lastMarker != null) lastMarker.setHovered(false);
|
||||||
lastMarker = marker;
|
lastMarker = marker;
|
||||||
@ -295,6 +114,22 @@ public class MapPanel extends JPanel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
if(startPos != null) {
|
||||||
|
if(e.getButton() == 1) {
|
||||||
|
int result = JOptionPane.showOptionDialog(frame, "What do you want to do", "Bulk Marking", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] {"Complete", "Uncomplete", "Cancel"}, "Complete");
|
||||||
|
if(result == 2) return;
|
||||||
|
List<Marker> markers = getMarkers(getMarkedArea(), zoom);
|
||||||
|
if(markers.isEmpty()) return;
|
||||||
|
boolean completion = result == 0;
|
||||||
|
Registry.INSTANCE.setBulkOperation(true);
|
||||||
|
markers.forEach(T -> T.setCompletion(completion));
|
||||||
|
Registry.INSTANCE.setBulkOperation(false);
|
||||||
|
startPos = null;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Point hover = screenToMap(e.getPoint());
|
Point hover = screenToMap(e.getPoint());
|
||||||
Marker marker = findMarker(hover, zoom);
|
Marker marker = findMarker(hover, zoom);
|
||||||
if(marker == null) return;
|
if(marker == null) return;
|
||||||
@ -314,6 +149,14 @@ public class MapPanel extends JPanel {
|
|||||||
addMouseMotionListener(adapter);
|
addMouseMotionListener(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProgressListener(Runnable run) {
|
||||||
|
this.progressUpdate = run;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startBulkMarking(Point point) {
|
||||||
|
this.startPos = this.screenToMap(point);
|
||||||
|
}
|
||||||
|
|
||||||
public void onImported() {
|
public void onImported() {
|
||||||
markers.forEach(Marker::updateCompletion);
|
markers.forEach(Marker::updateCompletion);
|
||||||
EventQueue.invokeLater(this::repaint);
|
EventQueue.invokeLater(this::repaint);
|
||||||
@ -370,6 +213,47 @@ public class MapPanel extends JPanel {
|
|||||||
for(Marker marker : visibleMarkers) {
|
for(Marker marker : visibleMarkers) {
|
||||||
marker.drawHover(g2, (float)zoom);
|
marker.drawHover(g2, (float)zoom);
|
||||||
}
|
}
|
||||||
|
if(startPos != null && lastPos != null) {
|
||||||
|
Point start = new Point(startPos);
|
||||||
|
Point end = new Point(lastPos);
|
||||||
|
if(start.x > end.x) {
|
||||||
|
int x = start.x;
|
||||||
|
start.x = end.x;
|
||||||
|
end.x = x;
|
||||||
|
}
|
||||||
|
if(start.y > end.y) {
|
||||||
|
int y = start.y;
|
||||||
|
start.y = end.y;
|
||||||
|
end.y = y;
|
||||||
|
}
|
||||||
|
g2.setColor(Color.BLUE);
|
||||||
|
g2.drawRect(start.x, start.y, end.x-start.x, end.y-start.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rectangle getMarkedArea() {
|
||||||
|
Point start = new Point(startPos);
|
||||||
|
Point end = new Point(lastPos);
|
||||||
|
if(start.x > end.x) {
|
||||||
|
int x = start.x;
|
||||||
|
start.x = end.x;
|
||||||
|
end.x = x;
|
||||||
|
}
|
||||||
|
if(start.y > end.y) {
|
||||||
|
int y = start.y;
|
||||||
|
start.y = end.y;
|
||||||
|
end.y = y;
|
||||||
|
}
|
||||||
|
return new Rectangle(start.x, start.y, end.x-start.x, end.y-start.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Marker> getMarkers(Rectangle rect, float scale) {
|
||||||
|
List<Marker> markers = new ArrayList<>();
|
||||||
|
for(int i = 0,m=visibleMarkers.size();i<m;i++) {
|
||||||
|
Marker marker = visibleMarkers.get(i);
|
||||||
|
if(marker.collides(rect, scale)) markers.add(marker);
|
||||||
|
}
|
||||||
|
return markers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Marker findMarker(Point point, float scale) {
|
private Marker findMarker(Point point, float scale) {
|
||||||
|
@ -5,6 +5,7 @@ import java.awt.Color;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import speiger.src.data.CollectableType;
|
import speiger.src.data.CollectableType;
|
||||||
@ -48,6 +49,11 @@ public class Marker {
|
|||||||
return mouse.x >= point.x - rad && mouse.x <= point.x + rad && mouse.y >= point.y - rad && mouse.y <= point.y + rad;
|
return mouse.x >= point.x - rad && mouse.x <= point.x + rad && mouse.y >= point.y - rad && mouse.y <= point.y + rad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean collides(Rectangle rect, float scale) {
|
||||||
|
int rad = Math.clamp((int)(32 / scale), 5, 32)>>1;
|
||||||
|
return rect.intersects(point.x-rad, point.y-rad, rad*2, rad*2);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isHovered() {
|
public boolean isHovered() {
|
||||||
return hovered;
|
return hovered;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user