Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding force view to commander gui, mouse clicks and more #6612

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions megamek/i18n/megamek/client/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2618,6 +2618,12 @@ MovementDisplay.butUnload=Unload
MovementDisplay.butUp=Get Up
MovementDisplay.moveChaff=Deploy Chaff
MovementDisplay.butWalk=Walk
MovementDisplay.butWaypoint=Waypoint
MovementDisplay.butWaypointAdd=Add Waypoint
MovementDisplay.butWaypointSet=Set Waypoints
MovementDisplay.butWaypointClear=Clear Waypoints
MovementDisplay.butWaypointUndo=Undo Waypoint

MovementDisplay.butVLand=V Land
MovementDisplay.butVTakeOff=V Lift Off
MovementDisplay.moveShakeOff=Shake Off
Expand Down
19 changes: 12 additions & 7 deletions megamek/src/megamek/client/ui/dialogs/UnitDisplayDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import megamek.client.ui.swing.ClientGUI;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.util.UIUtil;
import megamek.common.annotations.Nullable;

public class UnitDisplayDialog extends JDialog {
//region Variable Declarations
Expand All @@ -37,7 +38,7 @@ public class UnitDisplayDialog extends JDialog {
//endregion Variable Declarations

//region Constructors
public UnitDisplayDialog(final JFrame frame, final ClientGUI clientGUI) {
public UnitDisplayDialog(JFrame frame, @Nullable ClientGUI clientGUI) {
super(frame, "", false);
this.setTitle(Messages.getString("ClientGUI.MekDisplay"));

Expand Down Expand Up @@ -76,7 +77,9 @@ public void saveSettings() {
GUIP.setUnitDisplayNontabbedPosY(getLocation().y);
GUIP.setUnitDisplayNonTabbedSizeWidth(getSize().width);
GUIP.setUnitDisplayNonTabbedSizeHeight(getSize().height);
clientGUI.getUnitDisplay().saveSplitterLoc();
if (clientGUI != null) {
clientGUI.getUnitDisplay().saveSplitterLoc();
}
}
}
}
Expand All @@ -96,11 +99,13 @@ protected void processWindowEvent(WindowEvent e) {
*/
@Override
protected void processKeyEvent(KeyEvent evt) {
evt.setSource(clientGUI);
clientGUI.getMenuBar().dispatchEvent(evt);
// Make the source be the ClientGUI and not the dialog
// This prevents a ClassCastException in ToolTipManager
clientGUI.getCurrentPanel().dispatchEvent(evt);
if (clientGUI != null) {
evt.setSource(clientGUI);
clientGUI.getMenuBar().dispatchEvent(evt);
// Make the source be the ClientGUI and not the dialog
// This prevents a ClassCastException in ToolTipManager
clientGUI.getCurrentPanel().dispatchEvent(evt);
}
if (!evt.isConsumed()) {
super.processKeyEvent(evt);
}
Expand Down
9 changes: 8 additions & 1 deletion megamek/src/megamek/client/ui/swing/ClientGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
import static megamek.common.Configuration.gameSummaryImagesMMDir;

public class ClientGUI extends AbstractClientGUI implements BoardViewListener,
ActionListener, IPreferenceChangeListener, MekDisplayListener, ILocalBots, IDisconnectSilently, IHasUnitDisplay, IHasBoardView, IHasMenuBar, IHasCurrentPanel {
ActionListener, IPreferenceChangeListener, MekDisplayListener, ILocalBots, IDisconnectSilently, IHasUnitDisplay, IHasBoardView,
IHasMenuBar, IHasCurrentPanel, IDisplayedUnit {
private final static MMLogger logger = MMLogger.create(ClientGUI.class);

// region Variable Declarations
Expand Down Expand Up @@ -3264,11 +3265,17 @@ public JPanel getMainPanel() {
* another unit than the one that
* is selected to move or fire.
*/
@Override
@Nullable
public Entity getDisplayedUnit() {
return unitDisplay.getCurrentEntity();
}

@Override
public void setDisplayedUnit(Entity unit) {
unitDisplay.displayEntity(unit);
}

/**
* Returns the weapon that is currently selected in the Unit Display. The
* selection can be void for various
Expand Down
65 changes: 52 additions & 13 deletions megamek/src/megamek/client/ui/swing/CommanderGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@
import megamek.client.ui.swing.audio.AudioService;
import megamek.client.ui.swing.audio.SoundManager;
import megamek.client.ui.swing.audio.SoundType;
import megamek.client.ui.swing.minimap.BoardviewlessMinimap;
import megamek.client.ui.swing.commander.StrategicViewMenu;
import megamek.client.ui.swing.forceDisplay.PlainForceDisplayPanel;
import megamek.client.ui.swing.commander.StrategicView;
import megamek.client.ui.swing.overlay.ChatOverlay;
import megamek.client.ui.swing.tileset.TilesetManager;
import megamek.client.ui.swing.util.EntitySelectionService;
import megamek.client.ui.swing.util.MegaMekController;
import megamek.client.ui.swing.util.UIUtil;
import megamek.common.Configuration;
import megamek.common.Coords;
import megamek.common.Entity;
import megamek.common.enums.GamePhase;
import megamek.common.event.GameListenerAdapter;
Expand All @@ -39,33 +44,37 @@
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.*;

/**
* @author Luana Coppio
*/
public class CommanderGUI extends Thread implements IClientGUI, ILocalBots {
public class CommanderGUI extends Thread implements IClientGUI, ILocalBots, IDisplayedUnit {
private static final MMLogger logger = MMLogger.create(CommanderGUI.class);
private final Client client;
private final MegaMekController controller;
private final Map<String, AbstractClient> localBots;
private JPanel centerPanel;
private final JFrame frame;
private BoardviewlessMinimap minimap;
private boolean isLoading;
private JProgressBar progressBar;
private boolean alive = true;

private StrategicView strategicView;
private final AudioService audioService;
private BotCommandsPanel buttonPanel;
private JPanel centerPanel;
private StrategicViewMenu popup;
private transient final EntitySelectionService entitySelectionService;

private final TreeMap<Integer, String> splashImages = new TreeMap<>();
{
splashImages.put(0, Configuration.miscImagesDir() + "/acar_splash_hd.png");
}

public CommanderGUI(Client client, MegaMekController controller) {
frame = new JFrame(Messages.getString("ClientGUI.mini.title"));
frame.setMinimumSize(new Dimension(800, 800));

this.client = client;
if (client instanceof HeadlessClient headlessClient) {
headlessClient.setSendDoneOnVictoryAutomatically(false);
Expand All @@ -75,8 +84,7 @@ public CommanderGUI(Client client, MegaMekController controller) {
this.isLoading = true;
this.audioService = new SoundManager();
this.audioService.loadSoundFiles();
frame = new JFrame(Messages.getString("ClientGUI.mini.title"));
frame.setMinimumSize(new Dimension(800, 800));
this.entitySelectionService = new EntitySelectionService(client.getLocalPlayer());
}

@Override
Expand All @@ -101,6 +109,7 @@ private void loop() {
awaitMillis = (targetFrameTimeNanos - elapsedNanos) / 1_000_000;
try {
Thread.sleep(Math.max(1, awaitMillis));
SwingUtilities.invokeLater(() -> strategicView.updateUI());
} catch (InterruptedException e) {
logger.error("Interrupted while waiting for next frame", e);
alive = false;
Expand Down Expand Up @@ -128,9 +137,9 @@ public void initialize() {
progressBar.setIndeterminate(true);
progressBar.setStringPainted(true);
progressBar.setVisible(true);
minimap = new BoardviewlessMinimap(client);
strategicView = new StrategicView(client, this);
var chatOverlay = new ChatOverlay(8);
minimap.addOverlay(chatOverlay);
strategicView.addOverlay(chatOverlay);
centerPanel.add(splashImage, BorderLayout.CENTER);
centerPanel.add(progressBar, BorderLayout.SOUTH);

Expand All @@ -145,7 +154,13 @@ public void initialize() {
buttonPanel = new BotCommandsPanel(this.client, audioService, controller);
buttonPanel.useSpaceForPauseUnpause();

var jScroll = new JScrollPane(entityListEntries);
JPanel jScroll;
try {
jScroll = new PlainForceDisplayPanel(this.getFrame(), getClient().getGame(), getClient(), new TilesetManager(getClient().getGame()),
null, this);
} catch (Exception e) {
throw new RuntimeException(e);
}
jScroll.setMinimumSize(new Dimension(-1, 20));
jScroll.setPreferredSize(new Dimension(-1, 300));

Expand Down Expand Up @@ -233,7 +248,7 @@ private void setupMinimap() {
if (isLoading) {
isLoading = false;
centerPanel.remove(0);
centerPanel.add(minimap, BorderLayout.CENTER, 0);
centerPanel.add(strategicView, BorderLayout.CENTER, 0);
audioService.playSound(SoundType.BING_MY_TURN);
SwingUtilities.invokeLater(() -> progressBar.setIndeterminate(false));
}
Expand Down Expand Up @@ -291,4 +306,28 @@ public void enableReady() {
setupMinimap();
}
}

public EntitySelectionService getEntitySelectionService() {
return entitySelectionService;
}

@Override
public Entity getDisplayedUnit() {
return entitySelectionService.getSelectedUnits().stream().findFirst().orElse(null);
}

@Override
public void setDisplayedUnit(Entity entity) {
this.entitySelectionService.setSelectedUnits(entity);
}

@Override
public Collection<Entity> getSelectedUnits() {
return entitySelectionService.getSelectedUnits();
}

private boolean fillPopup(Coords coords) {
popup = new StrategicViewMenu(coords, client, this);
return popup.getHasMenu();
}
}
38 changes: 38 additions & 0 deletions megamek/src/megamek/client/ui/swing/IDisplayedUnit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2025 - The MegaMek Team. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*/

package megamek.client.ui.swing;

import megamek.common.Entity;
import megamek.common.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;

public interface IDisplayedUnit {

/**
* @return The unit currently shown in the Unit Display. Note: This can be a
* another unit than the one that
* is selected to move or fire.
*/
@Nullable Entity getDisplayedUnit();

void setDisplayedUnit(@Nullable Entity unit);

default Collection<Entity> getSelectedUnits() {
return Collections.singleton(getDisplayedUnit());
}
}
2 changes: 1 addition & 1 deletion megamek/src/megamek/client/ui/swing/MapMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ private JMenu createGMSpecialCommandsMenu() {
new RescueCommand(null, null)
).forEach(cmd -> {
JMenuItem item = new JMenuItem(cmd.getLongName());
item.addActionListener(evt -> new ClientCommandPanel(gui.getFrame(), gui, cmd, coords).setVisible(true));
item.addActionListener(evt -> new ClientCommandPanel(gui.getFrame(), client, cmd, coords).setVisible(true));
menu.add(item);
});

Expand Down
Loading
Loading