Skip to content

Commit

Permalink
Use bindings and properties for team card controllers (#2926)
Browse files Browse the repository at this point in the history
* Use bindings and properties for team card controllers

* Fix tests
  • Loading branch information
Sheikah45 committed Feb 24, 2023
1 parent 6752359 commit c19e7c2
Show file tree
Hide file tree
Showing 31 changed files with 604 additions and 513 deletions.
6 changes: 6 additions & 0 deletions src/main/java/com/faforever/client/chat/ChatListItemCell.java
@@ -1,7 +1,9 @@
package com.faforever.client.chat;

import com.faforever.client.game.GameTooltipController;
import com.faforever.client.theme.UiService;
import javafx.scene.Node;
import javafx.scene.control.Tooltip;
import org.fxmisc.flowless.Cell;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
Expand All @@ -19,6 +21,10 @@ public ChatListItemCell(UiService uiService) {
chatUserItemController = uiService.loadFxml("theme/chat/chat_user_item.fxml");
}

public void installGameTooltip(GameTooltipController gameTooltipController, Tooltip tooltip) {
chatUserItemController.installGameTooltip(gameTooltipController, tooltip);
}

@Override
public boolean isReusable() {
return true;
Expand Down
Expand Up @@ -59,8 +59,6 @@
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Slf4j
Expand Down Expand Up @@ -92,9 +90,7 @@ public class ChatUserItemController implements Controller<Node> {
private Tooltip avatarTooltip;
private Tooltip statusTooltip;
private Tooltip countryTooltip;
private Tooltip gameInfoTooltip;
private Tooltip noteTooltip;
private GameTooltipController gameInfoController;

public void initialize() {
initializeTooltips();
Expand Down Expand Up @@ -139,38 +135,9 @@ private void initializeStatusTooltip() {
Tooltip.install(gameStatusImageView, statusTooltip);
}

public void onMapImageViewMouseExited() {
if (gameInfoTooltip == null || gameInfoController == null) {
return;
}
Tooltip.uninstall(mapImageView, gameInfoTooltip);
gameInfoTooltip = null;
gameInfoController = null;
}

public void onMapImageViewMouseEntered() {
PlayerBean player = Optional.ofNullable(chatUser.get()).flatMap(ChatChannelUser::getPlayer).orElse(null);
if (player == null || gameInfoTooltip != null || gameInfoController != null) {
return;
}
gameInfoController = prepareGameInfoController(player.getGame());
gameInfoTooltip = prepareGameInfoTooltip(gameInfoController);
gameInfoController.displayGame();
Tooltip.install(mapImageView, gameInfoTooltip);
}

private GameTooltipController prepareGameInfoController(GameBean game) {
GameTooltipController controller = uiService.loadFxml("theme/play/game_tooltip.fxml");
controller.setShowMods(false);
controller.setGame(game);
return controller;
}

private Tooltip prepareGameInfoTooltip(GameTooltipController controller) {
Tooltip tooltip = JavaFxUtil.createCustomTooltip(controller.getRoot());
tooltip.setShowDelay(Duration.ZERO);
tooltip.setShowDuration(Duration.seconds(30));
return tooltip;
public void installGameTooltip(GameTooltipController gameInfoController, Tooltip tooltip) {
mapImageView.setOnMouseEntered(event -> gameInfoController.gameProperty().bind(chatUser.flatMap(ChatChannelUser::playerProperty).flatMap(PlayerBean::gameProperty)));
Tooltip.install(mapImageView, tooltip);
}

public void onContextMenuRequested(ContextMenuEvent event) {
Expand Down
Expand Up @@ -3,6 +3,7 @@
import com.faforever.client.filter.ChatUserFilterController;
import com.faforever.client.fx.Controller;
import com.faforever.client.fx.JavaFxUtil;
import com.faforever.client.game.GameTooltipController;
import com.faforever.client.i18n.I18n;
import com.faforever.client.preferences.ChatPrefs;
import com.faforever.client.theme.UiService;
Expand All @@ -25,12 +26,14 @@
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Popup;
import javafx.stage.PopupWindow;
import javafx.stage.PopupWindow.AnchorLocation;
import javafx.util.Duration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -75,6 +78,8 @@ public class ChatUserListController implements Controller<VBox> {
public Button listCustomizationButton;
public VBox userListContainer;
private VirtualFlow<ChatListItem, Cell<ChatListItem, Node>> chatItemListView;
private GameTooltipController gameInfoController;
private Tooltip gameTooltip;

private Popup filterPopup;

Expand All @@ -96,6 +101,7 @@ public class ChatUserListController implements Controller<VBox> {
public void initialize() {
initializeFilter();
initializeList();
initializeGameTooltip();
}

public void dispose() {
Expand All @@ -120,7 +126,8 @@ public void setChatChannel(ChatChannel chatChannel) {
categoryFilteredList.predicateProperty()
.bind(chatUserFilterController.predicateProperty()
.map(filterPredicate -> filterPredicate.and(item -> item.user() != null && item.category() == category)));
JavaFxUtil.runLater(() -> unfilteredSource.add(new ChatListItem(null, category, chatChannel.getName(), Bindings.size(categoryFilteredList).asObject())));
JavaFxUtil.runLater(() -> unfilteredSource.add(new ChatListItem(null, category, chatChannel.getName(), Bindings.size(categoryFilteredList)
.asObject())));
});

JavaFxUtil.addListener(users, new WeakListChangeListener<>(channelUserListListener));
Expand All @@ -131,9 +138,19 @@ public void setChatChannel(ChatChannel chatChannel) {
private ChatListItemCell createCellWithItem(ChatListItem item) {
ChatListItemCell cell = chatListItemCellFactory.getObject();
cell.updateItem(item);
cell.installGameTooltip(gameInfoController, gameTooltip);
return cell;
}

private void initializeGameTooltip() {
gameInfoController = uiService.loadFxml("theme/play/game_tooltip.fxml");
gameInfoController.setShowMods(false);

gameTooltip = JavaFxUtil.createCustomTooltip(gameInfoController.getRoot());
gameTooltip.setShowDelay(Duration.ZERO);
gameTooltip.setShowDuration(Duration.seconds(30));
}

private void initializeList() {
chatItemListView = VirtualFlow.createVertical(items, this::createCellWithItem, Gravity.FRONT);
VirtualizedScrollPane<VirtualFlow<ChatListItem, Cell<ChatListItem, Node>>> scrollPane = new VirtualizedScrollPane<>(chatItemListView);
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/com/faforever/client/domain/GameBean.java
Expand Up @@ -29,6 +29,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
Expand All @@ -38,8 +39,8 @@
@ToString(onlyExplicitlyIncluded = true)
@Value
public class GameBean {
public static final Integer OBSERVERS_TEAM = -1;
public static final Integer NO_TEAM = 1;
public static final int OBSERVERS_TEAM = -1;
public static final int NO_TEAM = 1;

StringProperty host = new SimpleStringProperty();
@ToString.Include
Expand All @@ -65,7 +66,7 @@ public class GameBean {
* Maps a sim mod's UID to its name.
*/
ReadOnlyMapWrapper<String, String> simMods = new ReadOnlyMapWrapper<>(FXCollections.emptyObservableMap());
ReadOnlyMapWrapper<Integer, Set<Integer>> teams = new ReadOnlyMapWrapper<>(FXCollections.emptyObservableMap());
ReadOnlyMapWrapper<Integer, List<Integer>> teams = new ReadOnlyMapWrapper<>(FXCollections.emptyObservableMap());
ObservableValue<Set<Integer>> allPlayersInGame = teams.map(team -> team.values()
.stream()
.flatMap(Collection::stream)
Expand All @@ -75,7 +76,7 @@ public class GameBean {
@Getter(AccessLevel.NONE)
ObservableValue<Set<Integer>> activePlayersInGame = teams.map(team -> team.entrySet()
.stream()
.filter(entry -> !OBSERVERS_TEAM.equals(entry.getKey()))
.filter(entry -> OBSERVERS_TEAM != entry.getKey())
.map(Entry::getValue)
.flatMap(Collection::stream)
.collect(Collectors.toSet()))
Expand Down Expand Up @@ -262,15 +263,15 @@ public ReadOnlyMapProperty<String, String> simModsProperty() {
/**
* Returns an unmodifiable map that maps team numbers (1, 2, ...) to a list of player ids.
*/
public Map<Integer, Set<Integer>> getTeams() {
public Map<Integer, List<Integer>> getTeams() {
return teams.get();
}

public void setTeams(Map<Integer, Set<Integer>> teams) {
public void setTeams(Map<Integer, List<Integer>> teams) {
this.teams.set(teams == null ? FXCollections.emptyObservableMap() : FXCollections.unmodifiableObservableMap(FXCollections.observableMap(teams)));
}

public ReadOnlyMapProperty<Integer, Set<Integer>> teamsProperty() {
public ReadOnlyMapProperty<Integer, List<Integer>> teamsProperty() {
return teams.getReadOnlyProperty();
}

Expand Down
24 changes: 4 additions & 20 deletions src/main/java/com/faforever/client/game/CustomGamesController.java
Expand Up @@ -4,22 +4,19 @@
import com.faforever.client.filter.CustomGamesFilterController;
import com.faforever.client.fx.AbstractViewController;
import com.faforever.client.fx.JavaFxUtil;
import com.faforever.client.fx.SimpleChangeListener;
import com.faforever.client.fx.SimpleInvalidationListener;
import com.faforever.client.game.GamesTilesContainerController.TilesSortingOrder;
import com.faforever.client.i18n.I18n;
import com.faforever.client.main.event.HostGameEvent;
import com.faforever.client.main.event.NavigateEvent;
import com.faforever.client.map.generator.MapGeneratedEvent;
import com.faforever.client.preferences.Preferences;
import com.faforever.client.preferences.PreferencesService;
import com.faforever.client.theme.UiService;
import com.faforever.client.ui.dialog.Dialog;
import com.faforever.client.ui.preferences.event.GameDirectoryChooseEvent;
import com.faforever.client.util.PopupUtil;
import com.faforever.commons.lobby.GameStatus;
import com.faforever.commons.lobby.GameType;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import javafx.beans.binding.Bindings;
Expand Down Expand Up @@ -59,7 +56,6 @@ public class CustomGamesController extends AbstractViewController<Node> {

private final UiService uiService;
private final GameService gameService;
private final PreferencesService preferencesService;
private final EventBus eventBus;
private final I18n i18n;
private final Preferences preferences;
Expand All @@ -85,7 +81,6 @@ public class CustomGamesController extends AbstractViewController<Node> {
private GamesTilesContainerController gamesTilesContainerController;

private final Predicate<GameBean> openGamesPredicate = game -> game.getStatus() == GameStatus.OPEN && game.getGameType() == GameType.CUSTOM;
private final SimpleChangeListener<GameBean> gameChangeListener = this::setSelectedGame;

public void initialize() {
JavaFxUtil.bindManagedToVisible(chooseSortingTypeChoiceBox);
Expand Down Expand Up @@ -145,8 +140,8 @@ public TilesSortingOrder fromString(String string) {
preferences.setGamesViewMode(((ToggleButton) newValue).getId());
});

JavaFxUtil.bind(gameDetailPane.visibleProperty(), toggleGameDetailPaneButton.selectedProperty());
JavaFxUtil.bind(gameDetailPane.managedProperty(), gameDetailPane.visibleProperty());
gameDetailPane.visibleProperty().bind(toggleGameDetailPaneButton.selectedProperty());
gameDetailPane.managedProperty().bind(gameDetailPane.visibleProperty());

toggleGameDetailPaneButton.selectedProperty().bindBidirectional(preferences.showGameDetailsSidePaneProperty());

Expand Down Expand Up @@ -203,7 +198,7 @@ public void onTableButtonClicked() {
disposeGamesContainer();

gamesTableController = uiService.loadFxml("theme/play/games_table.fxml");
JavaFxUtil.addListener(gamesTableController.selectedGameProperty(), gameChangeListener);
gameDetailController.gameProperty().bind(gamesTableController.selectedGameProperty());
gamesTableController.initializeGameTable(filteredItems);
populateContainer(gamesTableController.getRoot());
}
Expand All @@ -221,7 +216,7 @@ public void onTilesButtonClicked() {
disposeGamesContainer();

gamesTilesContainerController = uiService.loadFxml("theme/play/games_tiles_container.fxml");
JavaFxUtil.addListener(gamesTilesContainerController.selectedGameProperty(), gameChangeListener);
gameDetailController.gameProperty().bind(gamesTilesContainerController.selectedGameProperty());
populateContainer(gamesTilesContainerController.getRoot());
gamesTilesContainerController.createTiledFlowPane(filteredItems, chooseSortingTypeChoiceBox);
}
Expand All @@ -243,19 +238,8 @@ public void onMapGeneratedEvent(MapGeneratedEvent event) {

private void disposeGamesContainer() {
if (gamesTilesContainerController != null) {
JavaFxUtil.removeListener(gamesTilesContainerController.selectedGameProperty(), gameChangeListener);
gamesTilesContainerController.removeListeners();
}

if (gamesTableController != null) {
JavaFxUtil.removeListener(gamesTableController.selectedGameProperty(), gameChangeListener);
gamesTableController.removeListeners();
}
}

@VisibleForTesting
void setSelectedGame(GameBean game) {
gameDetailController.setGame(game);
}

public void onFilterButtonClicked() {
Expand Down

0 comments on commit c19e7c2

Please sign in to comment.