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:
Speiger 2025-08-05 00:20:21 +02:00
parent f7f5b1dc74
commit 525071fca4
5 changed files with 292 additions and 192 deletions

View File

@ -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()

View 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;
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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;
} }