mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-17 01:31:01 +00:00
Added user management dummy icon to RaceBoard
This commit is contained in:
1 parent
fa921cb4a5
commit
c9f012fda3
2 files changed
+481
-460
No files matched your search
@@ -655,7 +655,7 @@ img.openColumn {
|
||||
|
||||
.RegattaAndRaceTime-Header {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
right: 55px;
|
||||
top: 13px;
|
||||
text-align: right;
|
||||
color: white;
|
||||
@@ -752,4 +752,22 @@ img.openColumn {
|
||||
|
||||
.Media-Select-Popup .Caption {
|
||||
padding: 4px 10px;
|
||||
}
|
||||
|
||||
.User-Management-Icon {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
vertical-align: middle;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: contain;
|
||||
background-image: url('images/home/loggedout.svg');
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
.User-Management-Icon.loggedin {
|
||||
background-image: url('images/home/loggedin.svg');
|
||||
}
|
||||
+462
-459
@@ -1,459 +1,462 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
import com.google.gwt.core.shared.GWT;
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
import com.google.gwt.user.client.Command;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.MenuBar;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.UIObject;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.BoatDTO;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.common.dto.FleetDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceDTO;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorColorProvider;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorColorProviderImpl;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
|
||||
import com.sap.sailing.gwt.ui.client.GlobalNavigationPanel;
|
||||
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.client.MediaServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.RaceTimePanel;
|
||||
import com.sap.sailing.gwt.ui.client.RaceTimesInfoProvider;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.media.MediaPlayerManagerComponent;
|
||||
import com.sap.sailing.gwt.ui.client.media.PopupPositionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.EditMarkPassingsPanel;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorRaceChart;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.WindChart;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.WindChartSettings;
|
||||
import com.sap.sailing.gwt.ui.client.shared.filter.FilterWithUI;
|
||||
import com.sap.sailing.gwt.ui.client.shared.filter.LeaderboardFetcher;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapResources;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.CompetitorFilterPanel;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.ExplicitRaceColumnSelectionWithPreselectedRace;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettingsFactory;
|
||||
import com.sap.sse.common.filter.FilterSet;
|
||||
import com.sap.sse.common.settings.AbstractSettings;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.player.TimeRangeWithZoomModel;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentViewer;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
|
||||
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
/**
|
||||
* A view showing a list of components visualizing a race from the regattas announced by calls to {@link #fillRegattas(List)}.
|
||||
* The race selection is provided by a {@link RaceSelectionProvider} for which this is a {@link RaceSelectionChangeListener listener}.
|
||||
* {@link RaceIdentifier}-based race selection changes are converted to {@link RaceDTO} objects using the {@link #racesByIdentifier}
|
||||
* map maintained during {@link #fillRegattas(List)}. The race selection provider is expected to be single selection only.
|
||||
*
|
||||
* @author Frank Mittag, Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class RaceBoardPanel extends SimplePanel implements LeaderboardUpdateListener, PopupPositionProvider, RequiresResize {
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final MediaServiceAsync mediaService;
|
||||
private final UUID eventId;
|
||||
private final StringMessages stringMessages;
|
||||
private final ErrorReporter errorReporter;
|
||||
private final RaceBoardViewConfiguration raceboardViewConfiguration;
|
||||
private String raceBoardName;
|
||||
|
||||
private final List<ComponentViewer> componentViewers;
|
||||
private RaceTimePanel timePanel;
|
||||
private final Timer timer;
|
||||
private final UserAgentDetails userAgent;
|
||||
private final CompetitorSelectionProvider competitorSelectionProvider;
|
||||
private final TimeRangeWithZoomModel timeRangeWithZoomModel;
|
||||
private final RegattaAndRaceIdentifier selectedRaceIdentifier;
|
||||
|
||||
private final String leaderboardName;
|
||||
private final LeaderboardPanel leaderboardPanel;
|
||||
private WindChart windChart;
|
||||
private MultiCompetitorRaceChart competitorChart;
|
||||
private EditMarkPassingsPanel editMarkPassingPanel;
|
||||
|
||||
/**
|
||||
* The component viewer in <code>ONESCREEN</code> view mode. <code>null</code> if in <code>CASCADE</code> view mode
|
||||
*/
|
||||
private SideBySideComponentViewer leaderboardAndMapViewer;
|
||||
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
|
||||
private final RaceTimesInfoProvider raceTimesInfoProvider;
|
||||
private RaceMap raceMap;
|
||||
|
||||
private final FlowPanel raceInformationHeader;
|
||||
private final FlowPanel regattaAndRaceTimeInformationHeader;
|
||||
private boolean currentRaceHasBeenSelectedOnce;
|
||||
|
||||
private static final RaceMapResources raceMapResources = GWT.create(RaceMapResources.class);
|
||||
|
||||
/**
|
||||
* @param eventId
|
||||
* an optional event that can be used for "back"-navigation in case the race board shows a race in the
|
||||
* context of an event; may be <code>null</code>.
|
||||
* @param isScreenLargeEnoughToOfferChartSupport
|
||||
* if the screen is large enough to display charts such as the competitor chart or the wind chart, a
|
||||
* padding is provided for the RaceTimePanel that aligns its right border with that of the charts, and
|
||||
* the charts are created. This decision is made once on startup in the {@link RaceBoardEntryPoint} class.
|
||||
*/
|
||||
public RaceBoardPanel(SailingServiceAsync sailingService, MediaServiceAsync mediaService,
|
||||
UserService userService, AsyncActionsExecutor asyncActionsExecutor, Map<CompetitorDTO, BoatDTO> competitorsAndTheirBoats,
|
||||
Timer timer, RegattaAndRaceIdentifier selectedRaceIdentifier, String leaderboardName,
|
||||
String leaderboardGroupName, UUID eventId, RaceBoardViewConfiguration raceboardViewConfiguration,
|
||||
ErrorReporter errorReporter, final StringMessages stringMessages,
|
||||
UserAgentDetails userAgent, RaceTimesInfoProvider raceTimesInfoProvider, boolean showMapControls, boolean isScreenLargeEnoughToOfferChartSupport) {
|
||||
this.sailingService = sailingService;
|
||||
this.mediaService = mediaService;
|
||||
this.stringMessages = stringMessages;
|
||||
this.raceboardViewConfiguration = raceboardViewConfiguration;
|
||||
this.raceTimesInfoProvider = raceTimesInfoProvider;
|
||||
this.errorReporter = errorReporter;
|
||||
this.userAgent = userAgent;
|
||||
this.timer = timer;
|
||||
this.eventId = eventId;
|
||||
this.currentRaceHasBeenSelectedOnce = false;
|
||||
this.leaderboardName = leaderboardName;
|
||||
this.selectedRaceIdentifier = selectedRaceIdentifier;
|
||||
this.setRaceBoardName(selectedRaceIdentifier.getRaceName());
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
FlowPanel mainPanel = new ResizableFlowPanel();
|
||||
mainPanel.setSize("100%", "100%");
|
||||
setWidget(mainPanel);
|
||||
raceInformationHeader = new FlowPanel();
|
||||
raceInformationHeader.setStyleName("RegattaRaceInformation-Header");
|
||||
regattaAndRaceTimeInformationHeader = new FlowPanel();
|
||||
regattaAndRaceTimeInformationHeader.setStyleName("RegattaAndRaceTime-Header");
|
||||
timeRangeWithZoomModel = new TimeRangeWithZoomModel();
|
||||
componentViewers = new ArrayList<ComponentViewer>();
|
||||
final CompetitorColorProvider colorProvider = new CompetitorColorProviderImpl(selectedRaceIdentifier, competitorsAndTheirBoats);
|
||||
competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */ true, colorProvider);
|
||||
|
||||
raceMapResources.combinedWindPanelStyle().ensureInjected();
|
||||
raceMap = new RaceMap(sailingService, asyncActionsExecutor, errorReporter, timer,
|
||||
competitorSelectionProvider, stringMessages, showMapControls, getConfiguration().isShowViewStreamlets(), getConfiguration().isShowViewStreamletColors(), getConfiguration().isShowViewSimulation(),
|
||||
selectedRaceIdentifier, raceMapResources.combinedWindPanelStyle(), /* showHeaderPanel */ true) {
|
||||
private static final String INDENT_SMALL_CONTROL_STYLE = "indentsmall";
|
||||
private static final String INDENT_BIG_CONTROL_STYLE = "indentbig";
|
||||
@Override
|
||||
public void onResize() {
|
||||
super.onResize();
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
// Show/hide the leaderboard panels toggle button text based on the race map height
|
||||
leaderboardAndMapViewer.setLeftComponentToggleButtonTextVisibilityAndDraggerPosition(raceMap.getOffsetHeight() > 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLeftControlsIndentStyle() {
|
||||
// Calculate style name for left control indent based on race map height an leaderboard panel visibility
|
||||
if (raceMap.getOffsetHeight() <= 300) {
|
||||
return INDENT_BIG_CONTROL_STYLE;
|
||||
}
|
||||
if (leaderboardPanel.isVisible() && raceMap.getOffsetHeight() <= 500) {
|
||||
return INDENT_SMALL_CONTROL_STYLE;
|
||||
}
|
||||
return super.getLeftControlsIndentStyle();
|
||||
}
|
||||
};
|
||||
CompetitorFilterPanel competitorSearchTextBox = new CompetitorFilterPanel(competitorSelectionProvider, stringMessages, raceMap,
|
||||
new LeaderboardFetcher() {
|
||||
@Override
|
||||
public LeaderboardDTO getLeaderboard() {
|
||||
return leaderboardPanel.getLeaderboard();
|
||||
}
|
||||
}, selectedRaceIdentifier);
|
||||
raceMap.getLeftHeaderPanel().add(raceInformationHeader);
|
||||
raceMap.getRightHeaderPanel().add(regattaAndRaceTimeInformationHeader);
|
||||
|
||||
// Determine if the screen is large enough to initially display the leaderboard panel on the left side of the
|
||||
// map based on the initial screen width. Afterwards, the leaderboard panel visibility can be toggled as usual.
|
||||
boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard = Document.get().getClientWidth() >= 1024;
|
||||
leaderboardPanel = createLeaderboardPanel(leaderboardName, leaderboardGroupName, competitorSearchTextBox, isScreenLargeEnoughToInitiallyDisplayLeaderboard);
|
||||
leaderboardPanel.setTitle(stringMessages.leaderboard());
|
||||
leaderboardPanel.getElement().getStyle().setMarginLeft(6, Unit.PX);
|
||||
leaderboardPanel.getElement().getStyle().setMarginTop(10, Unit.PX);
|
||||
createOneScreenView(leaderboardName, leaderboardGroupName, eventId, mainPanel, showMapControls, isScreenLargeEnoughToOfferChartSupport, isScreenLargeEnoughToInitiallyDisplayLeaderboard, raceMap, userService); // initializes the raceMap field
|
||||
leaderboardPanel.addLeaderboardUpdateListener(this);
|
||||
// in case the URL configuration contains the name of a competitors filter set we try to activate it
|
||||
// FIXME the competitorsFilterSets has now moved to CompetitorSearchTextBox (which should probably be renamed); pass on the parameters to the LeaderboardPanel and see what it does with it
|
||||
if (raceboardViewConfiguration.getActiveCompetitorsFilterSetName() != null) {
|
||||
for (FilterSet<CompetitorDTO, FilterWithUI<CompetitorDTO>> filterSet : competitorSearchTextBox.getCompetitorsFilterSets()
|
||||
.getFilterSets()) {
|
||||
if (filterSet.getName().equals(raceboardViewConfiguration.getActiveCompetitorsFilterSetName())) {
|
||||
competitorSearchTextBox.getCompetitorsFilterSets().setActiveFilterSet(filterSet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
timePanel = new RaceTimePanel(timer, timeRangeWithZoomModel, stringMessages, raceTimesInfoProvider,
|
||||
raceboardViewConfiguration.isCanReplayDuringLiveRaces(), isScreenLargeEnoughToOfferChartSupport, selectedRaceIdentifier);
|
||||
timeRangeWithZoomModel.addTimeZoomChangeListener(timePanel);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(timePanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param event
|
||||
* an optional event; may be <code>null</code> or else can be used to show some context information in
|
||||
* the {@link GlobalNavigationPanel}.
|
||||
* @param isScreenLargeEnoughToOfferChartSupport
|
||||
* if the screen is large enough to display charts such as the competitor chart or the wind chart, a
|
||||
* padding is provided for the RaceTimePanel that aligns its right border with that of the charts, and
|
||||
* the charts are created.
|
||||
* @param isScreenLargeEnoughToInitiallyDisplayLeaderboard TODO
|
||||
*/
|
||||
private void createOneScreenView(String leaderboardName, String leaderboardGroupName, UUID event, FlowPanel mainPanel,
|
||||
boolean showMapControls, boolean isScreenLargeEnoughToOfferChartSupport, boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard, RaceMap raceMap, UserService userService) {
|
||||
// create the default leaderboard and select the right race
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
List<Component<?>> components = new ArrayList<Component<?>>();
|
||||
if (isScreenLargeEnoughToOfferChartSupport) {
|
||||
competitorChart = new MultiCompetitorRaceChart(sailingService, asyncActionsExecutor, competitorSelectionProvider, selectedRaceIdentifier,
|
||||
timer, timeRangeWithZoomModel, stringMessages, errorReporter, true, true, leaderboardGroupName, leaderboardName);
|
||||
competitorChart.getEntryWidget().setTitle(stringMessages.competitorCharts());
|
||||
competitorChart.setVisible(false);
|
||||
components.add(competitorChart);
|
||||
windChart = new WindChart(sailingService, selectedRaceIdentifier, timer, timeRangeWithZoomModel, new WindChartSettings(),
|
||||
stringMessages, asyncActionsExecutor, errorReporter, /* compactChart */ true);
|
||||
windChart.setVisible(false);
|
||||
windChart.getEntryWidget().setTitle(stringMessages.windChart());
|
||||
components.add(windChart);
|
||||
editMarkPassingPanel = new EditMarkPassingsPanel(sailingService, selectedRaceIdentifier,
|
||||
stringMessages, competitorSelectionProvider, errorReporter, timer);
|
||||
editMarkPassingPanel.setLeaderboard(leaderboardPanel.getLeaderboard());
|
||||
editMarkPassingPanel.getEntryWidget().setTitle(stringMessages.editMarkPassings());
|
||||
components.add(editMarkPassingPanel);
|
||||
}
|
||||
boolean autoSelectMedia = getConfiguration().isAutoSelectMedia();
|
||||
MediaPlayerManagerComponent mediaPlayerManagerComponent = new MediaPlayerManagerComponent(
|
||||
selectedRaceIdentifier, raceTimesInfoProvider, timer, mediaService, userService, stringMessages,
|
||||
errorReporter, userAgent, this, autoSelectMedia);
|
||||
leaderboardAndMapViewer = new SideBySideComponentViewer(leaderboardPanel, raceMap, mediaPlayerManagerComponent, components, stringMessages, userService, editMarkPassingPanel);
|
||||
componentViewers.add(leaderboardAndMapViewer);
|
||||
for (ComponentViewer componentViewer : componentViewers) {
|
||||
mainPanel.add(componentViewer.getViewerWidget());
|
||||
}
|
||||
boolean showLeaderboard = getConfiguration().isShowLeaderboard() && isScreenLargeEnoughToInitiallyDisplayLeaderboard;
|
||||
setLeaderboardVisible(showLeaderboard);
|
||||
if (isScreenLargeEnoughToOfferChartSupport) {
|
||||
setWindChartVisible(getConfiguration().isShowWindChart());
|
||||
setCompetitorChartVisible(getConfiguration().isShowCompetitorsChart());
|
||||
}
|
||||
// make sure to load leaderboard data for filtering to work
|
||||
if (!showLeaderboard) {
|
||||
leaderboardPanel.setVisible(true);
|
||||
leaderboardPanel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private <SettingsType extends AbstractSettings> void addSettingsMenuItem(MenuBar settingsMenu, final Component<SettingsType> component) {
|
||||
if (component.hasSettings()) {
|
||||
settingsMenu.addItem(component.getLocalizedShortName(), new Command() {
|
||||
public void execute() {
|
||||
new SettingsDialog<SettingsType>(component, stringMessages).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private LeaderboardPanel createLeaderboardPanel(String leaderboardName, String leaderboardGroupName,
|
||||
CompetitorFilterPanel competitorSearchTextBox, boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard) {
|
||||
LeaderboardSettings leaderBoardSettings = LeaderboardSettingsFactory.getInstance()
|
||||
.createNewSettingsForPlayMode(timer.getPlayMode(),
|
||||
/* nameOfRaceToSort */ selectedRaceIdentifier.getRaceName(),
|
||||
/* nameOfRaceColumnToShow */ null, /* nameOfRaceToShow */ selectedRaceIdentifier.getRaceName(),
|
||||
new ExplicitRaceColumnSelectionWithPreselectedRace(selectedRaceIdentifier), /* showRegattaRank */ false,
|
||||
/*showCompetitorSailIdColumn*/true,
|
||||
/* don't showCompetitorFullNameColumn in case screen is so small that we don't
|
||||
* even display the leaderboard initially */ isScreenLargeEnoughToInitiallyDisplayLeaderboard);
|
||||
return new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderBoardSettings, selectedRaceIdentifier != null, selectedRaceIdentifier,
|
||||
competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter, stringMessages,
|
||||
userAgent, /* showRaceDetails */ true, competitorSearchTextBox,
|
||||
/* showSelectionCheckbox */ true, raceTimesInfoProvider, /* autoExpandLastRaceColumn */ false,
|
||||
/* don't adjust the timer's delay from the leaderboard; control it solely from the RaceTimesInfoProvider */ false,
|
||||
/*autoApplyTopNFilter*/ false, /*showCompetitorFilterStatus*/ false);
|
||||
}
|
||||
|
||||
private void setComponentVisible(ComponentViewer componentViewer, Component<?> component, boolean visible) {
|
||||
component.setVisible(visible);
|
||||
componentViewer.forceLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the leaderboard open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the leaderboard, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
*
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the leaderboard shall be open/visible
|
||||
*/
|
||||
public void setLeaderboardVisible(boolean visible) {
|
||||
setComponentVisible(leaderboardAndMapViewer, leaderboardPanel, visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the wind chart open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the wind chart, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
*
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the wind chart shall be open/visible
|
||||
*/
|
||||
public void setWindChartVisible(boolean visible) {
|
||||
setComponentVisible(leaderboardAndMapViewer, windChart, visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the competitor chart open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the competitor chart, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
*
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the competitor chart shall be open/visible
|
||||
*/
|
||||
public void setCompetitorChartVisible(boolean visible) {
|
||||
setComponentVisible(leaderboardAndMapViewer, competitorChart, visible);
|
||||
}
|
||||
|
||||
public RaceTimePanel getTimePanel() {
|
||||
return timePanel;
|
||||
}
|
||||
|
||||
protected SailingServiceAsync getSailingService() {
|
||||
return sailingService;
|
||||
}
|
||||
|
||||
protected String getRaceBoardName() {
|
||||
return raceBoardName;
|
||||
}
|
||||
|
||||
protected void setRaceBoardName(String raceBoardName) {
|
||||
this.raceBoardName = raceBoardName;
|
||||
}
|
||||
|
||||
protected ErrorReporter getErrorReporter() {
|
||||
return errorReporter;
|
||||
}
|
||||
|
||||
public RaceBoardViewConfiguration getConfiguration() {
|
||||
return raceboardViewConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatedLeaderboard(LeaderboardDTO leaderboard) {
|
||||
leaderboardAndMapViewer.setLeftComponentWidth(leaderboardPanel.getContentPanel().getOffsetWidth());
|
||||
if (editMarkPassingPanel != null) {
|
||||
editMarkPassingPanel.setLeaderboard(leaderboard);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) {
|
||||
if (!currentRaceHasBeenSelectedOnce) {
|
||||
FleetDTO fleet = raceColumn.getFleet(raceIdentifier);
|
||||
String seriesName = raceColumn.getSeriesName();
|
||||
if (LeaderboardNameConstants.DEFAULT_SERIES_NAME.equals(seriesName)) {
|
||||
seriesName = "";
|
||||
}
|
||||
String fleetForRaceName = fleet==null?"":fleet.getName();
|
||||
if (fleetForRaceName.equals(LeaderboardNameConstants.DEFAULT_FLEET_NAME)) {
|
||||
fleetForRaceName = "";
|
||||
} else {
|
||||
fleetForRaceName = (seriesName.isEmpty() ? "" : " - ") + fleetForRaceName;
|
||||
}
|
||||
final Label raceNameLabel = new Label(stringMessages.race() + " " + raceColumn.getRaceColumnName());
|
||||
raceNameLabel.setStyleName("RaceName-Label");
|
||||
final Label raceAdditionalInformationLabel = new Label(seriesName + fleetForRaceName);
|
||||
raceAdditionalInformationLabel.setStyleName("RaceSeriesAndFleet-Label");
|
||||
raceInformationHeader.clear();
|
||||
raceInformationHeader.add(raceNameLabel);
|
||||
raceInformationHeader.add(raceAdditionalInformationLabel);
|
||||
final Anchor regattaNameAnchor = new Anchor(raceIdentifier.getRegattaName());
|
||||
regattaNameAnchor.setTitle(raceIdentifier.getRegattaName());
|
||||
if (eventId != null) {
|
||||
String link = EntryPointLinkFactory.createLeaderboardPlaceLink(eventId.toString(), leaderboardName);
|
||||
regattaNameAnchor.setHref(link);
|
||||
} else {
|
||||
String leaderboardGroupNameParam = Window.Location.getParameter("leaderboardGroupName");
|
||||
if(leaderboardGroupNameParam != null) {
|
||||
Map<String, String> leaderboardGroupLinkParameters = new HashMap<String, String>();
|
||||
leaderboardGroupLinkParameters.put("showRaceDetails", "true");
|
||||
leaderboardGroupLinkParameters.put("leaderboardGroupName", leaderboardGroupNameParam);
|
||||
String leaderBoardGroupLink = EntryPointLinkFactory.createLeaderboardGroupLink(leaderboardGroupLinkParameters);
|
||||
regattaNameAnchor.setHref(leaderBoardGroupLink);
|
||||
} else {
|
||||
// fallback
|
||||
regattaNameAnchor.setHref("javascript:window.history.back();");
|
||||
}
|
||||
}
|
||||
regattaNameAnchor.setStyleName("RegattaName-Anchor");
|
||||
Label raceTimeLabel = computeRaceInformation(raceColumn, fleet);
|
||||
raceTimeLabel.setStyleName("RaceTime-Label");
|
||||
regattaAndRaceTimeInformationHeader.clear();
|
||||
regattaAndRaceTimeInformationHeader.add(regattaNameAnchor);
|
||||
regattaAndRaceTimeInformationHeader.add(raceTimeLabel);
|
||||
currentRaceHasBeenSelectedOnce = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIObject getXPositionUiObject() {
|
||||
return timePanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIObject getYPositionUiObject() {
|
||||
return timePanel;
|
||||
}
|
||||
|
||||
private Label computeRaceInformation(RaceColumnDTO raceColumn, FleetDTO fleet) {
|
||||
Label raceInformationLabel = new Label();
|
||||
raceInformationLabel.setStyleName("Race-Time-Label");
|
||||
DateTimeFormat formatter = DateTimeFormat.getFormat("E d/M/y");
|
||||
raceInformationLabel.setText(formatter.format(raceColumn.getStartDate(fleet)));
|
||||
return raceInformationLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResize() {
|
||||
Widget child = getWidget();
|
||||
if (child != null && child instanceof RequiresResize) {
|
||||
((RequiresResize) child).onResize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
import com.google.gwt.core.shared.GWT;
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
import com.google.gwt.user.client.Command;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.MenuBar;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.UIObject;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.BoatDTO;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.common.dto.FleetDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceDTO;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorColorProvider;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorColorProviderImpl;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
|
||||
import com.sap.sailing.gwt.ui.client.GlobalNavigationPanel;
|
||||
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.client.MediaServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.RaceTimePanel;
|
||||
import com.sap.sailing.gwt.ui.client.RaceTimesInfoProvider;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.media.MediaPlayerManagerComponent;
|
||||
import com.sap.sailing.gwt.ui.client.media.PopupPositionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.EditMarkPassingsPanel;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorRaceChart;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.WindChart;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.WindChartSettings;
|
||||
import com.sap.sailing.gwt.ui.client.shared.filter.FilterWithUI;
|
||||
import com.sap.sailing.gwt.ui.client.shared.filter.LeaderboardFetcher;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapResources;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.CompetitorFilterPanel;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.ExplicitRaceColumnSelectionWithPreselectedRace;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettingsFactory;
|
||||
import com.sap.sse.common.filter.FilterSet;
|
||||
import com.sap.sse.common.settings.AbstractSettings;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.player.TimeRangeWithZoomModel;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentViewer;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
|
||||
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
/**
|
||||
* A view showing a list of components visualizing a race from the regattas announced by calls to {@link #fillRegattas(List)}.
|
||||
* The race selection is provided by a {@link RaceSelectionProvider} for which this is a {@link RaceSelectionChangeListener listener}.
|
||||
* {@link RaceIdentifier}-based race selection changes are converted to {@link RaceDTO} objects using the {@link #racesByIdentifier}
|
||||
* map maintained during {@link #fillRegattas(List)}. The race selection provider is expected to be single selection only.
|
||||
*
|
||||
* @author Frank Mittag, Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class RaceBoardPanel extends SimplePanel implements LeaderboardUpdateListener, PopupPositionProvider, RequiresResize {
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final MediaServiceAsync mediaService;
|
||||
private final UUID eventId;
|
||||
private final StringMessages stringMessages;
|
||||
private final ErrorReporter errorReporter;
|
||||
private final RaceBoardViewConfiguration raceboardViewConfiguration;
|
||||
private String raceBoardName;
|
||||
|
||||
private final List<ComponentViewer> componentViewers;
|
||||
private RaceTimePanel timePanel;
|
||||
private final Timer timer;
|
||||
private final UserAgentDetails userAgent;
|
||||
private final CompetitorSelectionProvider competitorSelectionProvider;
|
||||
private final TimeRangeWithZoomModel timeRangeWithZoomModel;
|
||||
private final RegattaAndRaceIdentifier selectedRaceIdentifier;
|
||||
|
||||
private final String leaderboardName;
|
||||
private final LeaderboardPanel leaderboardPanel;
|
||||
private WindChart windChart;
|
||||
private MultiCompetitorRaceChart competitorChart;
|
||||
private EditMarkPassingsPanel editMarkPassingPanel;
|
||||
|
||||
/**
|
||||
* The component viewer in <code>ONESCREEN</code> view mode. <code>null</code> if in <code>CASCADE</code> view mode
|
||||
*/
|
||||
private SideBySideComponentViewer leaderboardAndMapViewer;
|
||||
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
|
||||
private final RaceTimesInfoProvider raceTimesInfoProvider;
|
||||
private RaceMap raceMap;
|
||||
|
||||
private final FlowPanel raceInformationHeader;
|
||||
private final FlowPanel regattaAndRaceTimeInformationHeader;
|
||||
private final Anchor userManagementMenu = new Anchor();
|
||||
private boolean currentRaceHasBeenSelectedOnce;
|
||||
|
||||
private static final RaceMapResources raceMapResources = GWT.create(RaceMapResources.class);
|
||||
|
||||
/**
|
||||
* @param eventId
|
||||
* an optional event that can be used for "back"-navigation in case the race board shows a race in the
|
||||
* context of an event; may be <code>null</code>.
|
||||
* @param isScreenLargeEnoughToOfferChartSupport
|
||||
* if the screen is large enough to display charts such as the competitor chart or the wind chart, a
|
||||
* padding is provided for the RaceTimePanel that aligns its right border with that of the charts, and
|
||||
* the charts are created. This decision is made once on startup in the {@link RaceBoardEntryPoint} class.
|
||||
*/
|
||||
public RaceBoardPanel(SailingServiceAsync sailingService, MediaServiceAsync mediaService,
|
||||
UserService userService, AsyncActionsExecutor asyncActionsExecutor, Map<CompetitorDTO, BoatDTO> competitorsAndTheirBoats,
|
||||
Timer timer, RegattaAndRaceIdentifier selectedRaceIdentifier, String leaderboardName,
|
||||
String leaderboardGroupName, UUID eventId, RaceBoardViewConfiguration raceboardViewConfiguration,
|
||||
ErrorReporter errorReporter, final StringMessages stringMessages,
|
||||
UserAgentDetails userAgent, RaceTimesInfoProvider raceTimesInfoProvider, boolean showMapControls, boolean isScreenLargeEnoughToOfferChartSupport) {
|
||||
this.sailingService = sailingService;
|
||||
this.mediaService = mediaService;
|
||||
this.stringMessages = stringMessages;
|
||||
this.raceboardViewConfiguration = raceboardViewConfiguration;
|
||||
this.raceTimesInfoProvider = raceTimesInfoProvider;
|
||||
this.errorReporter = errorReporter;
|
||||
this.userAgent = userAgent;
|
||||
this.timer = timer;
|
||||
this.eventId = eventId;
|
||||
this.currentRaceHasBeenSelectedOnce = false;
|
||||
this.leaderboardName = leaderboardName;
|
||||
this.selectedRaceIdentifier = selectedRaceIdentifier;
|
||||
this.setRaceBoardName(selectedRaceIdentifier.getRaceName());
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
FlowPanel mainPanel = new ResizableFlowPanel();
|
||||
mainPanel.setSize("100%", "100%");
|
||||
setWidget(mainPanel);
|
||||
raceInformationHeader = new FlowPanel();
|
||||
raceInformationHeader.setStyleName("RegattaRaceInformation-Header");
|
||||
regattaAndRaceTimeInformationHeader = new FlowPanel();
|
||||
regattaAndRaceTimeInformationHeader.setStyleName("RegattaAndRaceTime-Header");
|
||||
userManagementMenu.setStyleName("User-Management-Icon");
|
||||
timeRangeWithZoomModel = new TimeRangeWithZoomModel();
|
||||
componentViewers = new ArrayList<ComponentViewer>();
|
||||
final CompetitorColorProvider colorProvider = new CompetitorColorProviderImpl(selectedRaceIdentifier, competitorsAndTheirBoats);
|
||||
competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */ true, colorProvider);
|
||||
|
||||
raceMapResources.combinedWindPanelStyle().ensureInjected();
|
||||
raceMap = new RaceMap(sailingService, asyncActionsExecutor, errorReporter, timer,
|
||||
competitorSelectionProvider, stringMessages, showMapControls, getConfiguration().isShowViewStreamlets(), getConfiguration().isShowViewStreamletColors(), getConfiguration().isShowViewSimulation(),
|
||||
selectedRaceIdentifier, raceMapResources.combinedWindPanelStyle(), /* showHeaderPanel */ true) {
|
||||
private static final String INDENT_SMALL_CONTROL_STYLE = "indentsmall";
|
||||
private static final String INDENT_BIG_CONTROL_STYLE = "indentbig";
|
||||
@Override
|
||||
public void onResize() {
|
||||
super.onResize();
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
// Show/hide the leaderboard panels toggle button text based on the race map height
|
||||
leaderboardAndMapViewer.setLeftComponentToggleButtonTextVisibilityAndDraggerPosition(raceMap.getOffsetHeight() > 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLeftControlsIndentStyle() {
|
||||
// Calculate style name for left control indent based on race map height an leaderboard panel visibility
|
||||
if (raceMap.getOffsetHeight() <= 300) {
|
||||
return INDENT_BIG_CONTROL_STYLE;
|
||||
}
|
||||
if (leaderboardPanel.isVisible() && raceMap.getOffsetHeight() <= 500) {
|
||||
return INDENT_SMALL_CONTROL_STYLE;
|
||||
}
|
||||
return super.getLeftControlsIndentStyle();
|
||||
}
|
||||
};
|
||||
CompetitorFilterPanel competitorSearchTextBox = new CompetitorFilterPanel(competitorSelectionProvider, stringMessages, raceMap,
|
||||
new LeaderboardFetcher() {
|
||||
@Override
|
||||
public LeaderboardDTO getLeaderboard() {
|
||||
return leaderboardPanel.getLeaderboard();
|
||||
}
|
||||
}, selectedRaceIdentifier);
|
||||
raceMap.getLeftHeaderPanel().add(raceInformationHeader);
|
||||
raceMap.getRightHeaderPanel().add(regattaAndRaceTimeInformationHeader);
|
||||
raceMap.getRightHeaderPanel().add(userManagementMenu);
|
||||
|
||||
// Determine if the screen is large enough to initially display the leaderboard panel on the left side of the
|
||||
// map based on the initial screen width. Afterwards, the leaderboard panel visibility can be toggled as usual.
|
||||
boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard = Document.get().getClientWidth() >= 1024;
|
||||
leaderboardPanel = createLeaderboardPanel(leaderboardName, leaderboardGroupName, competitorSearchTextBox, isScreenLargeEnoughToInitiallyDisplayLeaderboard);
|
||||
leaderboardPanel.setTitle(stringMessages.leaderboard());
|
||||
leaderboardPanel.getElement().getStyle().setMarginLeft(6, Unit.PX);
|
||||
leaderboardPanel.getElement().getStyle().setMarginTop(10, Unit.PX);
|
||||
createOneScreenView(leaderboardName, leaderboardGroupName, eventId, mainPanel, showMapControls, isScreenLargeEnoughToOfferChartSupport, isScreenLargeEnoughToInitiallyDisplayLeaderboard, raceMap, userService); // initializes the raceMap field
|
||||
leaderboardPanel.addLeaderboardUpdateListener(this);
|
||||
// in case the URL configuration contains the name of a competitors filter set we try to activate it
|
||||
// FIXME the competitorsFilterSets has now moved to CompetitorSearchTextBox (which should probably be renamed); pass on the parameters to the LeaderboardPanel and see what it does with it
|
||||
if (raceboardViewConfiguration.getActiveCompetitorsFilterSetName() != null) {
|
||||
for (FilterSet<CompetitorDTO, FilterWithUI<CompetitorDTO>> filterSet : competitorSearchTextBox.getCompetitorsFilterSets()
|
||||
.getFilterSets()) {
|
||||
if (filterSet.getName().equals(raceboardViewConfiguration.getActiveCompetitorsFilterSetName())) {
|
||||
competitorSearchTextBox.getCompetitorsFilterSets().setActiveFilterSet(filterSet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
timePanel = new RaceTimePanel(timer, timeRangeWithZoomModel, stringMessages, raceTimesInfoProvider,
|
||||
raceboardViewConfiguration.isCanReplayDuringLiveRaces(), isScreenLargeEnoughToOfferChartSupport, selectedRaceIdentifier);
|
||||
timeRangeWithZoomModel.addTimeZoomChangeListener(timePanel);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(timePanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param event
|
||||
* an optional event; may be <code>null</code> or else can be used to show some context information in
|
||||
* the {@link GlobalNavigationPanel}.
|
||||
* @param isScreenLargeEnoughToOfferChartSupport
|
||||
* if the screen is large enough to display charts such as the competitor chart or the wind chart, a
|
||||
* padding is provided for the RaceTimePanel that aligns its right border with that of the charts, and
|
||||
* the charts are created.
|
||||
* @param isScreenLargeEnoughToInitiallyDisplayLeaderboard TODO
|
||||
*/
|
||||
private void createOneScreenView(String leaderboardName, String leaderboardGroupName, UUID event, FlowPanel mainPanel,
|
||||
boolean showMapControls, boolean isScreenLargeEnoughToOfferChartSupport, boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard, RaceMap raceMap, UserService userService) {
|
||||
// create the default leaderboard and select the right race
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
List<Component<?>> components = new ArrayList<Component<?>>();
|
||||
if (isScreenLargeEnoughToOfferChartSupport) {
|
||||
competitorChart = new MultiCompetitorRaceChart(sailingService, asyncActionsExecutor, competitorSelectionProvider, selectedRaceIdentifier,
|
||||
timer, timeRangeWithZoomModel, stringMessages, errorReporter, true, true, leaderboardGroupName, leaderboardName);
|
||||
competitorChart.getEntryWidget().setTitle(stringMessages.competitorCharts());
|
||||
competitorChart.setVisible(false);
|
||||
components.add(competitorChart);
|
||||
windChart = new WindChart(sailingService, selectedRaceIdentifier, timer, timeRangeWithZoomModel, new WindChartSettings(),
|
||||
stringMessages, asyncActionsExecutor, errorReporter, /* compactChart */ true);
|
||||
windChart.setVisible(false);
|
||||
windChart.getEntryWidget().setTitle(stringMessages.windChart());
|
||||
components.add(windChart);
|
||||
editMarkPassingPanel = new EditMarkPassingsPanel(sailingService, selectedRaceIdentifier,
|
||||
stringMessages, competitorSelectionProvider, errorReporter, timer);
|
||||
editMarkPassingPanel.setLeaderboard(leaderboardPanel.getLeaderboard());
|
||||
editMarkPassingPanel.getEntryWidget().setTitle(stringMessages.editMarkPassings());
|
||||
components.add(editMarkPassingPanel);
|
||||
}
|
||||
boolean autoSelectMedia = getConfiguration().isAutoSelectMedia();
|
||||
MediaPlayerManagerComponent mediaPlayerManagerComponent = new MediaPlayerManagerComponent(
|
||||
selectedRaceIdentifier, raceTimesInfoProvider, timer, mediaService, userService, stringMessages,
|
||||
errorReporter, userAgent, this, autoSelectMedia);
|
||||
leaderboardAndMapViewer = new SideBySideComponentViewer(leaderboardPanel, raceMap, mediaPlayerManagerComponent, components, stringMessages, userService, editMarkPassingPanel);
|
||||
componentViewers.add(leaderboardAndMapViewer);
|
||||
for (ComponentViewer componentViewer : componentViewers) {
|
||||
mainPanel.add(componentViewer.getViewerWidget());
|
||||
}
|
||||
boolean showLeaderboard = getConfiguration().isShowLeaderboard() && isScreenLargeEnoughToInitiallyDisplayLeaderboard;
|
||||
setLeaderboardVisible(showLeaderboard);
|
||||
if (isScreenLargeEnoughToOfferChartSupport) {
|
||||
setWindChartVisible(getConfiguration().isShowWindChart());
|
||||
setCompetitorChartVisible(getConfiguration().isShowCompetitorsChart());
|
||||
}
|
||||
// make sure to load leaderboard data for filtering to work
|
||||
if (!showLeaderboard) {
|
||||
leaderboardPanel.setVisible(true);
|
||||
leaderboardPanel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private <SettingsType extends AbstractSettings> void addSettingsMenuItem(MenuBar settingsMenu, final Component<SettingsType> component) {
|
||||
if (component.hasSettings()) {
|
||||
settingsMenu.addItem(component.getLocalizedShortName(), new Command() {
|
||||
public void execute() {
|
||||
new SettingsDialog<SettingsType>(component, stringMessages).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private LeaderboardPanel createLeaderboardPanel(String leaderboardName, String leaderboardGroupName,
|
||||
CompetitorFilterPanel competitorSearchTextBox, boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard) {
|
||||
LeaderboardSettings leaderBoardSettings = LeaderboardSettingsFactory.getInstance()
|
||||
.createNewSettingsForPlayMode(timer.getPlayMode(),
|
||||
/* nameOfRaceToSort */ selectedRaceIdentifier.getRaceName(),
|
||||
/* nameOfRaceColumnToShow */ null, /* nameOfRaceToShow */ selectedRaceIdentifier.getRaceName(),
|
||||
new ExplicitRaceColumnSelectionWithPreselectedRace(selectedRaceIdentifier), /* showRegattaRank */ false,
|
||||
/*showCompetitorSailIdColumn*/true,
|
||||
/* don't showCompetitorFullNameColumn in case screen is so small that we don't
|
||||
* even display the leaderboard initially */ isScreenLargeEnoughToInitiallyDisplayLeaderboard);
|
||||
return new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderBoardSettings, selectedRaceIdentifier != null, selectedRaceIdentifier,
|
||||
competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter, stringMessages,
|
||||
userAgent, /* showRaceDetails */ true, competitorSearchTextBox,
|
||||
/* showSelectionCheckbox */ true, raceTimesInfoProvider, /* autoExpandLastRaceColumn */ false,
|
||||
/* don't adjust the timer's delay from the leaderboard; control it solely from the RaceTimesInfoProvider */ false,
|
||||
/*autoApplyTopNFilter*/ false, /*showCompetitorFilterStatus*/ false);
|
||||
}
|
||||
|
||||
private void setComponentVisible(ComponentViewer componentViewer, Component<?> component, boolean visible) {
|
||||
component.setVisible(visible);
|
||||
componentViewer.forceLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the leaderboard open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the leaderboard, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
*
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the leaderboard shall be open/visible
|
||||
*/
|
||||
public void setLeaderboardVisible(boolean visible) {
|
||||
setComponentVisible(leaderboardAndMapViewer, leaderboardPanel, visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the wind chart open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the wind chart, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
*
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the wind chart shall be open/visible
|
||||
*/
|
||||
public void setWindChartVisible(boolean visible) {
|
||||
setComponentVisible(leaderboardAndMapViewer, windChart, visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the competitor chart open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the competitor chart, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
*
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the competitor chart shall be open/visible
|
||||
*/
|
||||
public void setCompetitorChartVisible(boolean visible) {
|
||||
setComponentVisible(leaderboardAndMapViewer, competitorChart, visible);
|
||||
}
|
||||
|
||||
public RaceTimePanel getTimePanel() {
|
||||
return timePanel;
|
||||
}
|
||||
|
||||
protected SailingServiceAsync getSailingService() {
|
||||
return sailingService;
|
||||
}
|
||||
|
||||
protected String getRaceBoardName() {
|
||||
return raceBoardName;
|
||||
}
|
||||
|
||||
protected void setRaceBoardName(String raceBoardName) {
|
||||
this.raceBoardName = raceBoardName;
|
||||
}
|
||||
|
||||
protected ErrorReporter getErrorReporter() {
|
||||
return errorReporter;
|
||||
}
|
||||
|
||||
public RaceBoardViewConfiguration getConfiguration() {
|
||||
return raceboardViewConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatedLeaderboard(LeaderboardDTO leaderboard) {
|
||||
leaderboardAndMapViewer.setLeftComponentWidth(leaderboardPanel.getContentPanel().getOffsetWidth());
|
||||
if (editMarkPassingPanel != null) {
|
||||
editMarkPassingPanel.setLeaderboard(leaderboard);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) {
|
||||
if (!currentRaceHasBeenSelectedOnce) {
|
||||
FleetDTO fleet = raceColumn.getFleet(raceIdentifier);
|
||||
String seriesName = raceColumn.getSeriesName();
|
||||
if (LeaderboardNameConstants.DEFAULT_SERIES_NAME.equals(seriesName)) {
|
||||
seriesName = "";
|
||||
}
|
||||
String fleetForRaceName = fleet==null?"":fleet.getName();
|
||||
if (fleetForRaceName.equals(LeaderboardNameConstants.DEFAULT_FLEET_NAME)) {
|
||||
fleetForRaceName = "";
|
||||
} else {
|
||||
fleetForRaceName = (seriesName.isEmpty() ? "" : " - ") + fleetForRaceName;
|
||||
}
|
||||
final Label raceNameLabel = new Label(stringMessages.race() + " " + raceColumn.getRaceColumnName());
|
||||
raceNameLabel.setStyleName("RaceName-Label");
|
||||
final Label raceAdditionalInformationLabel = new Label(seriesName + fleetForRaceName);
|
||||
raceAdditionalInformationLabel.setStyleName("RaceSeriesAndFleet-Label");
|
||||
raceInformationHeader.clear();
|
||||
raceInformationHeader.add(raceNameLabel);
|
||||
raceInformationHeader.add(raceAdditionalInformationLabel);
|
||||
final Anchor regattaNameAnchor = new Anchor(raceIdentifier.getRegattaName());
|
||||
regattaNameAnchor.setTitle(raceIdentifier.getRegattaName());
|
||||
if (eventId != null) {
|
||||
String link = EntryPointLinkFactory.createLeaderboardPlaceLink(eventId.toString(), leaderboardName);
|
||||
regattaNameAnchor.setHref(link);
|
||||
} else {
|
||||
String leaderboardGroupNameParam = Window.Location.getParameter("leaderboardGroupName");
|
||||
if(leaderboardGroupNameParam != null) {
|
||||
Map<String, String> leaderboardGroupLinkParameters = new HashMap<String, String>();
|
||||
leaderboardGroupLinkParameters.put("showRaceDetails", "true");
|
||||
leaderboardGroupLinkParameters.put("leaderboardGroupName", leaderboardGroupNameParam);
|
||||
String leaderBoardGroupLink = EntryPointLinkFactory.createLeaderboardGroupLink(leaderboardGroupLinkParameters);
|
||||
regattaNameAnchor.setHref(leaderBoardGroupLink);
|
||||
} else {
|
||||
// fallback
|
||||
regattaNameAnchor.setHref("javascript:window.history.back();");
|
||||
}
|
||||
}
|
||||
regattaNameAnchor.setStyleName("RegattaName-Anchor");
|
||||
Label raceTimeLabel = computeRaceInformation(raceColumn, fleet);
|
||||
raceTimeLabel.setStyleName("RaceTime-Label");
|
||||
regattaAndRaceTimeInformationHeader.clear();
|
||||
regattaAndRaceTimeInformationHeader.add(regattaNameAnchor);
|
||||
regattaAndRaceTimeInformationHeader.add(raceTimeLabel);
|
||||
currentRaceHasBeenSelectedOnce = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIObject getXPositionUiObject() {
|
||||
return timePanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIObject getYPositionUiObject() {
|
||||
return timePanel;
|
||||
}
|
||||
|
||||
private Label computeRaceInformation(RaceColumnDTO raceColumn, FleetDTO fleet) {
|
||||
Label raceInformationLabel = new Label();
|
||||
raceInformationLabel.setStyleName("Race-Time-Label");
|
||||
DateTimeFormat formatter = DateTimeFormat.getFormat("E d/M/y");
|
||||
raceInformationLabel.setText(formatter.format(raceColumn.getStartDate(fleet)));
|
||||
return raceInformationLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResize() {
|
||||
Widget child = getWidget();
|
||||
if (child != null && child instanceof RequiresResize) {
|
||||
((RequiresResize) child).onResize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user