Skip to content

Commit

Permalink
Redesign context menu (FAForever#2596)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marc-Spector authored and Chris Haggan committed Apr 15, 2022
1 parent 58719d8 commit 22eec11
Show file tree
Hide file tree
Showing 22 changed files with 271 additions and 7 deletions.
8 changes: 4 additions & 4 deletions readme.md
Expand Up @@ -32,12 +32,12 @@ A video tutorial is available [here](https://youtu.be/6gsHnt02I_Y). Don't forget
Learn how to install the client on Linux [here](https://github.com/FAForever/downlords-faf-client/wiki/Install-on-Linux)

## Open Source licenses
| | |
| | |
|----------------|-------------------------------|
|<img src="https://www.ej-technologies.com/images/product_banners/install4j_large.png" width="128">|Thanks to [ej-technologies](https://www.ej-technologies.com) for their [open source license](https://www.ej-technologies.com/buy/install4j/openSource). We use Install4j to build installers.|
|<img src="https://slack-files2.s3-us-west-2.amazonaws.com/avatars/2017-12-13/286651735269_a5ab3167acef52b0111e_512.png" width="128">| Thanks to [bugsnag](https://www.bugsnag.com) for their [open source license](https://www.bugsnag.com/open-source/). We use bugsnag for our error reporting.|
| <img src="https://www.ej-technologies.com/images/product_banners/install4j_large.png" width="128"> | Thanks to [ej-technologies](https://www.ej-technologies.com) for their [open source license](https://www.ej-technologies.com/buy/install4j/openSource). We use Install4j to build installers. |
| <img src="https://slack-files2.s3-us-west-2.amazonaws.com/avatars/2017-12-13/286651735269_a5ab3167acef52b0111e_512.png" width="128"> | Thanks to [bugsnag](https://www.bugsnag.com) for their [open source license](https://www.bugsnag.com/open-source/). We use bugsnag for our error reporting. |
|<img src="https://faforever.github.io/downlords-faf-client/images/yklogo.png" width="128">| Thanks to [YourKit](https://www.yourkit.com) for their open source license.|
|<img src="https://cdn.cms-twdigitalassets.com/content/dam/about-twitter/en/brand-toolkit/brand-download-img-1.jpg.twimg.2560.jpg" width="128">| Thanks to [Twemoji Twitter](https://twemoji.twitter.com/) for their open source license. We use and display emojis in the chats.|
| <img src="https://cdn.cms-twdigitalassets.com/content/dam/about-twitter/en/brand-toolkit/brand-download-img-1.jpg.twimg.2560.jpg" width="128"> | Thanks to [Twemoji Twitter](https://twemoji.twitter.com/) for their open source license. We use and display emojis in the chats. |


## Contribute
Expand Down
Expand Up @@ -8,7 +8,7 @@
import com.faforever.client.fx.contextmenu.AddFoeMenuItem;
import com.faforever.client.fx.contextmenu.AddFriendMenuItem;
import com.faforever.client.fx.contextmenu.BroadcastMessageMenuItem;
import com.faforever.client.fx.contextmenu.ChatUserColorPickerCustomMenuItemController;
import com.faforever.client.fx.contextmenu.ChangeUsernameColorMenuItem;
import com.faforever.client.fx.contextmenu.ContextMenuBuilder;
import com.faforever.client.fx.contextmenu.CopyUsernameMenuItem;
import com.faforever.client.fx.contextmenu.InvitePlayerMenuItem;
Expand Down Expand Up @@ -156,7 +156,7 @@ public void onContextMenuRequested(ContextMenuEvent event) {
.addItem(ShowPlayerInfoMenuItem.class, player)
.addItem(SendPrivateMessageMenuItem.class, chatUser.getUsername())
.addItem(CopyUsernameMenuItem.class, chatUser.getUsername())
.addCustomItem(uiService.loadFxml("theme/chat/color_picker_menu_item.fxml", ChatUserColorPickerCustomMenuItemController.class), chatUser)
.addItem(ChangeUsernameColorMenuItem.class, chatUser)
.addSeparator()
.addItem(SendPrivateMessageClanLeaderMenuItem.class, chatUser.getClan().orElse(null))
.addItem(OpenClanUrlMenuItem.class, chatUser.getClan().orElse(null))
Expand Down
@@ -1,6 +1,7 @@
package com.faforever.client.fx.contextmenu;

import javafx.scene.control.MenuItem;
import javafx.scene.layout.Region;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
Expand All @@ -20,11 +21,29 @@ private void finalizeProperties() {
if (isItemVisible()) {
setOnAction(event -> onClicked());
setText(getItemText());
setIcon();
} else {
setVisible(false);
}
}

private void setIcon() {
String styleIcon = getStyleIcon();
if (styleIcon != null) {
setGraphic(initializeIcon(styleIcon));
}
}

private Region initializeIcon(String styleIcon) {
Region iconView = new Region();
iconView.getStyleClass().addAll("icon", "icon16x16", styleIcon);
return iconView;
}

protected String getStyleIcon() {
return null; // by-default
}

protected abstract void onClicked();

protected abstract String getItemText();
Expand Down
Expand Up @@ -26,6 +26,11 @@ protected void onClicked() {
liveReplayService.stopTrackingLiveReplay();
}

@Override
protected String getStyleIcon() {
return "close-icon";
}

@Override
protected boolean isItemVisible() {
boolean isValid = object != null && object.getStartTime() != null;
Expand Down
Expand Up @@ -26,6 +26,11 @@ protected void onClicked() {
liveReplayService.stopTrackingLiveReplay();
}

@Override
protected String getStyleIcon() {
return "close-icon";
}

@Override
protected boolean isItemVisible() {
boolean isValid = object != null && object.getStartTime() != null;
Expand Down
@@ -0,0 +1,48 @@
package com.faforever.client.fx.contextmenu;

import com.faforever.client.chat.ChatChannelUser;
import com.faforever.client.i18n.I18n;
import com.faforever.client.preferences.PreferencesService;
import com.faforever.client.theme.UiService;
import com.faforever.client.ui.StageHolder;
import com.faforever.client.util.Assert;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import static com.faforever.client.chat.ChatColorMode.RANDOM;

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@RequiredArgsConstructor
public class ChangeUsernameColorMenuItem extends AbstractMenuItem<ChatChannelUser> {

private final PreferencesService preferencesService;
private final UiService uiService;
private final I18n i18n;
private final ContextMenuBuilder contextMenuBuilder;

@Override
protected void onClicked() {
Assert.checkNullIllegalState(object, "no chat user has been set");
Node node = getStyleableNode();
Bounds screenBounds = node.localToScreen(node.getBoundsInLocal());
contextMenuBuilder.newBuilder()
.addCustomItem(uiService.loadFxml("theme/chat/color_picker_menu_item.fxml", ChatUserColorPickerCustomMenuItemController.class), object)
.build()
.show(StageHolder.getStage(), screenBounds.getMinX(), screenBounds.getMinY());
}

@Override
protected boolean isItemVisible() {
return object != null && !preferencesService.getPreferences().getChat().getChatColorMode().equals(RANDOM);
}

@Override
protected String getItemText() {
return i18n.get("chat.userContext.changeColor");
}
}
Expand Up @@ -25,6 +25,11 @@ protected void onClicked() {
ClipboardUtil.copyToClipboard(object.getText());
}

@Override
protected String getStyleIcon() {
return "copy-icon";
}

@Override
protected boolean isItemVisible() {
return object != null && !StringUtils.isBlank(object.getText());
Expand Down
Expand Up @@ -22,6 +22,11 @@ protected void onClicked() {
ClipboardUtil.copyToClipboard(object);
}

@Override
protected String getStyleIcon() {
return "copy-icon";
}

@Override
protected boolean isItemVisible() {
return !StringUtils.isBlank(object);
Expand Down
Expand Up @@ -32,6 +32,11 @@ protected void onClicked() {
dialog.show();
}

@Override
protected String getStyleIcon() {
return "mode-edit-icon";
}

@Override
protected boolean isItemVisible() {
return object != null;
Expand Down
Expand Up @@ -38,6 +38,11 @@ protected boolean isItemVisible() {
.anyMatch(trackingLiveReplay -> !trackingLiveReplay.getGameId().equals(object.getId()) || trackingLiveReplay.getAction() != NOTIFY_ME);
}

@Override
protected String getStyleIcon() {
return "notification-none-icon";
}

@Override
protected String getItemText() {
return i18n.get("vault.liveReplays.contextMenu.notifyMe");
Expand Down
Expand Up @@ -29,6 +29,11 @@ protected void onClicked() {
reportDialogController.show();
}

@Override
protected String getStyleIcon() {
return "assignment-late-icon";
}

@Override
protected boolean isItemVisible() {
return object != null && object.getSocialStatus() != SELF;
Expand Down
Expand Up @@ -26,6 +26,11 @@ protected void onClicked() {
liveReplayService.performActionWhenAvailable(object, RUN_REPLAY);
}

@Override
protected String getStyleIcon() {
return "play-circle-outline-icon";
}

@Override
protected boolean isItemVisible() {
boolean isValid = object != null && object.getStartTime() != null;
Expand Down
Expand Up @@ -26,6 +26,11 @@ protected void onClicked() {
eventBus.post(new InitiatePrivateChatEvent(object.getLeader().getUsername()));
}

@Override
protected String getStyleIcon() {
return "bubble-icon";
}

@Override
protected boolean isItemVisible() {
return object != null && !playerService.getCurrentPlayer().getId().equals(object.getLeader().getId())
Expand Down
Expand Up @@ -28,6 +28,11 @@ protected void onClicked() {
eventBus.post(new InitiatePrivateChatEvent(object));
}

@Override
protected String getStyleIcon() {
return "bubble-icon";
}

@Override
protected boolean isItemVisible() {
return !StringUtils.isBlank(object)
Expand Down
Expand Up @@ -27,6 +27,11 @@ protected void onClicked() {
controller.show();
}

@Override
protected String getStyleIcon() {
return "info-icon";
}

@Override
protected boolean isItemVisible() {
return object != null;
Expand Down
Expand Up @@ -24,6 +24,11 @@ protected void onClicked() {
eventBus.post(new ShowUserReplaysEvent(object.getId()));
}

@Override
protected String getStyleIcon() {
return "search-icon";
}

@Override
protected boolean isItemVisible() {
return object != null;
Expand Down
Expand Up @@ -33,6 +33,11 @@ protected void onClicked() {
}
}

@Override
protected String getStyleIcon() {
return "play-circle-outline-icon";
}

@Override
protected boolean isItemVisible() {
return object != null && object.getStatus() == PlayerStatus.PLAYING;
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/i18n/messages.properties
Expand Up @@ -119,6 +119,7 @@ chat.userContext.viewReplays = View replays
chat.userContext.inviteToGame = Invite to party
chat.userContext.kick = Kick…
chat.userContext.ban = Ban…
chat.userContext.changeColor = Change color
chat.userContext.addNote = Add note
chat.userContext.editNote = Edit note
chat.userContext.removeNote = Remove note
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/theme/colors.css
Expand Up @@ -40,6 +40,10 @@
-fx-text-color: #fff;
-darkened-color: dimgrey;

-context-menu-color: #3c3f41;
-context-menu-border-color: #868686;
-menu-item-label-color: #DCDCDC;

FRIEND_IN_GAME_NOT_SELECTED_ITEM: rgba(42, 253, 53, 0.1);
FRIEND_IN_GAME_SELECTED_ITEM: rgba(42, 253, 53, 0.35);
}
24 changes: 24 additions & 0 deletions src/main/resources/theme/icons.css
Expand Up @@ -285,4 +285,28 @@

.settings-icon {
-fx-shape: "M8 10.344c1.281 0 2.344-1.063 2.344-2.344s-1.063-2.344-2.344-2.344-2.344 1.063-2.344 2.344 1.063 2.344 2.344 2.344zM12.969 8.656l1.406 1.094c0.125 0.094 0.156 0.281 0.063 0.438l-1.344 2.313c-0.094 0.156-0.25 0.188-0.406 0.125l-1.656-0.656c-0.344 0.25-0.719 0.5-1.125 0.656l-0.25 1.75c-0.031 0.156-0.156 0.281-0.313 0.281h-2.688c-0.156 0-0.281-0.125-0.313-0.281l-0.25-1.75c-0.406-0.156-0.781-0.375-1.125-0.656l-1.656 0.656c-0.156 0.063-0.313 0.031-0.406-0.125l-1.344-2.313c-0.094-0.156-0.063-0.344 0.063-0.438l1.406-1.094c-0.031-0.219-0.031-0.438-0.031-0.656s0-0.438 0.031-0.656l-1.406-1.094c-0.125-0.094-0.156-0.281-0.063-0.438l1.344-2.313c0.094-0.156 0.25-0.188 0.406-0.125l1.656 0.656c0.344-0.25 0.719-0.5 1.125-0.656l0.25-1.75c0.031-0.156 0.156-0.281 0.313-0.281h2.688c0.156 0 0.281 0.125 0.313 0.281l0.25 1.75c0.406 0.156 0.781 0.375 1.125 0.656l1.656-0.656c0.156-0.063 0.313-0.031 0.406 0.125l1.344 2.313c0.094 0.156 0.063 0.344-0.063 0.438l-1.406 1.094c0.031 0.219 0.031 0.438 0.031 0.656s0 0.438-0.031 0.656z";
}

.copy-icon {
-fx-shape: "M20 8v-8h-14l-6 6v18h12v8h20v-24h-12zM6 2.828v3.172h-3.172l3.172-3.172zM2 22v-14h6v-6h10v6l-6 6v8h-10zM18 10.828v3.172h-3.172l3.172-3.172zM30 30h-16v-14h6v-6h10v20z";
}

.bubble-icon {
-fx-shape: "M16 6c-1.717 0-3.375 0.271-4.928 0.804-1.46 0.502-2.76 1.211-3.863 2.108-2.069 1.681-3.209 3.843-3.209 6.088 0 1.259 0.35 2.481 1.039 3.63 0.711 1.185 1.781 2.268 3.093 3.133 0.949 0.625 1.587 1.623 1.755 2.747 0.056 0.375 0.091 0.753 0.105 1.129 0.233-0.194 0.461-0.401 0.684-0.624 0.755-0.755 1.774-1.172 2.828-1.172 0.168 0 0.336 0.011 0.505 0.032 0.655 0.083 1.325 0.126 1.99 0.126 1.717 0 3.375-0.271 4.928-0.804 1.46-0.502 2.76-1.211 3.863-2.108 2.069-1.681 3.209-3.843 3.209-6.088s-1.14-4.407-3.209-6.088c-1.104-0.897-2.404-1.606-3.863-2.108-1.553-0.534-3.211-0.804-4.928-0.804zM16 2v0c8.837 0 16 5.82 16 13s-7.163 13-16 13c-0.849 0-1.682-0.054-2.495-0.158-3.437 3.437-7.539 4.053-11.505 4.144v-0.841c2.142-1.049 4-2.961 4-5.145 0-0.305-0.024-0.604-0.068-0.897-3.619-2.383-5.932-6.024-5.932-10.103 0-7.18 7.163-13 16-13z";
}

.mode-edit-icon {
-fx-shape: "M20.719 7.031l-1.828 1.828-3.75-3.75 1.828-1.828c0.375-0.375 1.031-0.375 1.406 0l2.344 2.344c0.375 0.375 0.375 1.031 0 1.406zM3 17.25l11.063-11.063 3.75 3.75-11.063 11.063h-3.75v-3.75z";
}

.notification-none-icon {
-fx-shape: "M15.984 17.016v-6c0-2.484-1.5-4.5-3.984-4.5s-3.984 2.016-3.984 4.5v6h7.969zM18 15.984l2.016 2.016v0.984h-16.031v-0.984l2.016-2.016v-4.969c0-3.094 1.641-5.625 4.5-6.328v-0.703c0-0.844 0.656-1.5 1.5-1.5s1.5 0.656 1.5 1.5v0.703c2.859 0.703 4.5 3.281 4.5 6.328v4.969zM12 21.984c-1.078 0-2.016-0.891-2.016-1.969h4.031c0 1.078-0.938 1.969-2.016 1.969z";
}

.assignment-late-icon {
-fx-shape: "M288 192.75c18 0 31.5-15 31.5-33s-13.5-31.5-31.5-31.5-31.5 13.5-31.5 31.5 13.5 33 31.5 33zM319.5 480.75v-192h-63v192h63zM319.5 608.25v-64.5h-63v64.5h63zM511.5 128.25c34.5 0 64.5 30 64.5 64.5v447c0 34.5-30 64.5-64.5 64.5h-447c-34.5 0-64.5-30-64.5-64.5v-447c0-34.5 30-64.5 64.5-64.5h133.5c13.5-37.5 48-64.5 90-64.5s76.5 27 90 64.5h133.5z";
}

.play-circle-outline-icon {
-fx-shape: "M16 26.688c5.875 0 10.688-4.813 10.688-10.688s-4.813-10.688-10.688-10.688-10.688 4.813-10.688 10.688 4.813 10.688 10.688 10.688zM16 2.688c7.375 0 13.313 5.938 13.313 13.313s-5.938 13.313-13.313 13.313-13.313-5.938-13.313-13.313 5.938-13.313 13.313-13.313zM13.313 22v-12l8 6z";
}
21 changes: 20 additions & 1 deletion src/main/resources/theme/style.css
Expand Up @@ -114,7 +114,7 @@
-fx-background-color: -fx-background;
}

.query-filter .context-menu {
.query-filter {
-fx-background-color: -fx-background;
}

Expand Down Expand Up @@ -1445,3 +1445,22 @@
.clickable:hover {
-fx-background-color: -fx-hover-accent;
}

/***************** Root Context Menu ***************************/

.context-menu {
-fx-background-color: derive(-context-menu-color, 5%);
-fx-border-color: -context-menu-border-color;
-fx-border-width: 0.0625em; /* 1px */
-fx-border-radius: 0.1875em; /* 3px */
-fx-background-radius: 0.1875em; /* 3px */
}

.context-menu .separator .line {
-fx-border-color: derive(-context-menu-color, 30%) transparent transparent transparent
}

.menu-item > .label {
-fx-text-fill: -menu-item-label-color;
}

0 comments on commit 22eec11

Please sign in to comment.