implemented auto scaling of leaderboard for autoplay mode

This commit is contained in:
fmittag committed 2014-10-07 23:41:31 +02:00
1 parent 6adf2afd19
commit 3000f24a99
8 files changed
+203 -12

No files matched your search

@@ -2,5 +2,5 @@ package com.sap.sailing.gwt.autoplay.client.app;
public interface PlaceNavigator {
void goToStart();
void goToPlayer(String eventUuidAsString, String leaderboardIdAsNameString);
void goToPlayer(String eventUuidAsString, String leaderboardIdAsNameString, String leaderboardZoom);
}
@@ -18,8 +18,8 @@ public class PlaceNavigatorImpl implements PlaceNavigator {
}
@Override
public void goToPlayer(String eventUuidAsString, String leaderboardIdAsNameString) {
PlayerPlace playerPlace = new PlayerPlace(eventUuidAsString, leaderboardIdAsNameString);
public void goToPlayer(String eventUuidAsString, String leaderboardIdAsNameString, String leaderboardZoom) {
PlayerPlace playerPlace = new PlayerPlace(eventUuidAsString, leaderboardIdAsNameString, String.valueOf(leaderboardZoom));
placeController.goTo(playerPlace);
}
@@ -6,15 +6,23 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.TextAlign;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
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.gwt.autoplay.client.shared.header.SAPHeader;
import com.sap.sailing.gwt.common.client.CSS3Util;
import com.sap.sailing.gwt.common.client.i18n.TextMessages;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
@@ -57,6 +65,7 @@ public class AutoPlayController implements RaceTimesInfoProviderListener {
private LeaderboardDTO leaderboard;
private final String leaderboardName;
private final String leaderboardGroupName;
private final String leaderboardZoom;
private LeaderboardSettings leaderboardSettings;
// raceboard related attributes
@@ -65,15 +74,18 @@ public class AutoPlayController implements RaceTimesInfoProviderListener {
private boolean showWindChart;
private final RaceBoardViewConfiguration raceboardViewConfig;
private final PlayerView playerView;
private final int SAP_HEADER_HEIGHT = 80;
private Widget currentContentWidget;
public AutoPlayController(SailingServiceAsync sailingService, MediaServiceAsync mediaService,
ErrorReporter errorReporter, String leaderboardGroupName, String leaderboardName, UserAgentDetails userAgent,
ErrorReporter errorReporter, String leaderboardGroupName, String leaderboardName, final String leaderboardZoom, UserAgentDetails userAgent,
long delayToLiveInMillis, boolean showRaceDetails, RaceBoardViewConfiguration raceboardViewConfig, PlayerView playerView) {
this.raceboardViewConfig = raceboardViewConfig;
this.sailingService = sailingService;
this.mediaService = mediaService;
this.errorReporter = errorReporter;
this.leaderboardName = leaderboardName;
this.leaderboardZoom = leaderboardZoom;
this.leaderboardGroupName = leaderboardGroupName;
this.userAgent = userAgent;
this.showRaceDetails = showRaceDetails;
@@ -95,6 +107,15 @@ public class AutoPlayController implements RaceTimesInfoProviderListener {
raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, asyncActionsExecutor, errorReporter, new ArrayList<RegattaAndRaceIdentifier>(), 3000l);
raceTimesInfoProvider.addRaceTimesInfoProviderListener(this);
Window.addResizeHandler(new ResizeHandler() {
@Override
public void onResize(ResizeEvent event) {
if(leaderboardZoom != null && leaderboardZoom.equalsIgnoreCase("auto")) {
autoZoomContentWidget();
}
}
});
}
private LeaderboardPanel createLeaderboardPanel(String leaderboardGroupName, String leaderboardName, boolean showRaceDetails) {
@@ -112,7 +133,8 @@ public class AutoPlayController implements RaceTimesInfoProviderListener {
updateRaceTimesInfoProvider();
}
};
leaderboardPanel.getContentWidget().getElement().getStyle().setProperty("margin", "0 auto");
// leaderboardPanel.getContentWidget().getElement().getStyle().setProperty("margin", "0 auto");
leaderboardPanel.getContentWidget().getElement().getStyle().setPosition(Position.ABSOLUTE);
leaderboardPanel.getContentWidget().getElement().getStyle().setFontWeight(FontWeight.BOLD);
return leaderboardPanel;
}
@@ -148,10 +170,26 @@ public class AutoPlayController implements RaceTimesInfoProviderListener {
playerView.clearDockPanel();
SAPHeader sapHeader = new SAPHeader(TextMessages.INSTANCE.leaderboard() + ": " + leaderboardName);
playerView.getDockPanel().addNorth(sapHeader, 80);
playerView.getDockPanel().addNorth(sapHeader, SAP_HEADER_HEIGHT);
LeaderboardPanel leaderboardPanel = createLeaderboardPanel(leaderboardGroupName, leaderboardName, showRaceDetails);
ScrollPanel leaderboardContentPanel = new ScrollPanel();
currentContentWidget = leaderboardPanel.getContentWidget();
if(leaderboardZoom != null) {
if(leaderboardZoom.equalsIgnoreCase("auto")) {
autoZoomContentWidget();
} else {
try {
Double zoom = Double.valueOf(leaderboardZoom);
scaleContentWidget(SAP_HEADER_HEIGHT, currentContentWidget, zoom);
} catch (NumberFormatException e) {
// do nothing
}
}
}
leaderboardContentPanel.getElement().getStyle().setTextAlign(TextAlign.CENTER);
leaderboardContentPanel.add(leaderboardPanel);
playerView.getDockPanel().add(leaderboardContentPanel);
@@ -161,7 +199,55 @@ public class AutoPlayController implements RaceTimesInfoProviderListener {
leaderboardTimer.setPlayMode(PlayModes.Live);
}
}
private void autoZoomContentWidget() {
if(currentContentWidget != null) {
Scheduler.get().scheduleFixedPeriod(new RepeatingCommand() {
public boolean execute () {
boolean invokeAgain = true;
if(currentContentWidget.getOffsetHeight() > 10) {
scaleContentWidget(SAP_HEADER_HEIGHT, currentContentWidget);
invokeAgain = false;
}
return invokeAgain;
}
}, 1000);
}
}
private void scaleContentWidget(int headerHeight, Widget contentWidget, double scaleFactor, double diffX) {
if(scaleFactor > 0.0) {
CSS3Util.setProperty(contentWidget.getElement().getStyle(),
"transform", "translateX(" + diffX / 2.0 + "px) scale(" + scaleFactor + ")");
CSS3Util.setProperty(contentWidget.getElement().getStyle(), "transformOrigin", "0 0");
}
}
private void scaleContentWidget(int headerHeight, Widget contentWidget, double scaleFactor) {
int clientWidth = Window.getClientWidth();
int contentWidth = contentWidget.getOffsetWidth();
double diffX = clientWidth - contentWidth * scaleFactor;
scaleContentWidget(headerHeight, contentWidget, scaleFactor, diffX);
}
private void scaleContentWidget(int headerHeight, Widget contentWidget) {
int clientWidth = Window.getClientWidth();
int clientHeight = Window.getClientHeight() - headerHeight;
int contentWidth = contentWidget.getOffsetWidth();
int contentHeight = contentWidget.getOffsetHeight();
double scaleFactorX = clientWidth / (double) contentWidth;
double scaleFactorY = clientHeight / (double) contentHeight;
Double scaleFactor = scaleFactorX > scaleFactorY ? scaleFactorY : scaleFactorX;
double diffX = clientWidth - contentWidth * scaleFactor;
scaleContentWidget(headerHeight, contentWidget, scaleFactor, diffX);
}
private void showRaceBoard() {
if (activeTvView != AutoPlayModes.Raceboard) {
playerView.clearDockPanel();
@@ -45,8 +45,8 @@ public class PlayerActivity extends AbstractActivity implements ErrorReporter {
panel.setWidget(view.asWidget());
autoPlayController = new AutoPlayController(clientFactory.getSailingService(), clientFactory.getMediaService(),
PlayerActivity.this, /*leaderboardGroupName*/ "" , playerPlace.getLeaderboardIdAsNameString(), userAgent, delayToLiveMillis,
showRaceDetails, readRaceboardConfiguration, view);
PlayerActivity.this, /*leaderboardGroupName*/ "" , playerPlace.getLeaderboardIdAsNameString(), playerPlace.getLeaderboardZoomAsString(),
userAgent, delayToLiveMillis, showRaceDetails, readRaceboardConfiguration, view);
autoPlayController.updatePlayMode(AutoPlayModes.Leaderboard);
}
@@ -6,20 +6,24 @@ import com.sap.sailing.gwt.common.client.AbstractBasePlace;
public class PlayerPlace extends AbstractBasePlace {
private final String eventUuidAsString;
private final String leaderboardIdAsNameString;
private final String leaderboardZoomAsString;
private final static String PARAM_EVENTID = "eventId";
private final static String PARAM_LEADEROARD_NAME = "leaderboardName";
private final static String PARAM_LEADEROARD_ZOOM = "leaderboardZoom";
public PlayerPlace(String url) {
super(url);
eventUuidAsString = getParameter(PARAM_EVENTID);
leaderboardIdAsNameString = getParameter(PARAM_LEADEROARD_NAME);
leaderboardZoomAsString = getParameter(PARAM_LEADEROARD_ZOOM);
}
public PlayerPlace(String eventUuidAsString, String leaderboardIdAsNameString) {
super(PARAM_EVENTID, eventUuidAsString, PARAM_LEADEROARD_NAME, leaderboardIdAsNameString);
public PlayerPlace(String eventUuidAsString, String leaderboardIdAsNameString, String leaderboardZoomAsString) {
super(PARAM_EVENTID, eventUuidAsString, PARAM_LEADEROARD_NAME, leaderboardIdAsNameString, PARAM_LEADEROARD_ZOOM, leaderboardZoomAsString);
this.eventUuidAsString = eventUuidAsString;
this.leaderboardIdAsNameString = leaderboardIdAsNameString;
this.leaderboardZoomAsString = leaderboardZoomAsString;
}
public String getEventUuidAsString() {
@@ -30,6 +34,10 @@ public class PlayerPlace extends AbstractBasePlace {
return leaderboardIdAsNameString;
}
public String getLeaderboardZoomAsString() {
return leaderboardZoomAsString;
}
public static class Tokenizer implements PlaceTokenizer<PlayerPlace> {
@Override
public String getToken(PlayerPlace place) {
@@ -8,12 +8,15 @@ import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.autoplay.client.app.PlaceNavigator;
import com.sap.sailing.gwt.common.client.SharedResources;
@@ -29,8 +32,12 @@ public class DesktopStartView extends Composite implements StartView {
@UiField(provided=true) ListBox eventSelectionBox;
@UiField(provided=true) ListBox leaderboardSelectionBox;
@UiField CheckBox leaderboardAutoZoomBox;
@UiField TextBox leaderboardZoomBox;
@UiField Button startAutoPlayButton;
@UiField DivElement leaderboardSelectionDiv;
@UiField DivElement leaderboardZoomDiv;
@UiField DivElement leaderboardAutoZoomDiv;
private final PlaceNavigator navigator;
private final List<EventDTO> events;
@@ -44,7 +51,10 @@ public class DesktopStartView extends Composite implements StartView {
leaderboardSelectionBox = new ListBox(false);
initWidget(uiBinder.createAndBindUi(this));
leaderboardAutoZoomBox.setValue(true);
leaderboardZoomBox.setEnabled(false);
leaderboardSelectionDiv.getStyle().setVisibility(Visibility.HIDDEN);
startAutoPlayButton.setEnabled(false);
startAutoPlayButton.addStyleName(SharedResources.INSTANCE.mainCss().buttoninactive());
@@ -92,11 +102,21 @@ public class DesktopStartView extends Composite implements StartView {
void startAutoPlayClicked(ClickEvent event) {
EventDTO selectedEvent = getSelectedEvent();
String selectedLeaderboardName = getSelectedLeaderboardName();
String leaderboardZoom = getLeaderboardZoom();
if(selectedEvent != null && selectedLeaderboardName != null) {
navigator.goToPlayer(selectedEvent.id.toString(), selectedLeaderboardName);
navigator.goToPlayer(selectedEvent.id.toString(), selectedLeaderboardName, leaderboardZoom);
}
}
@UiHandler("leaderboardAutoZoomBox")
public void onLeaderboardAutoZoomClicked(ValueChangeEvent<Boolean> ev) {
leaderboardZoomBox.setEnabled(!leaderboardAutoZoomBox.getValue());
}
private String getLeaderboardZoom() {
return leaderboardAutoZoomBox.getValue() == true ? "auto" : String.valueOf(leaderboardZoomBox.getValue());
}
private String getSelectedLeaderboardName() {
String result = null;
int selectedIndex = leaderboardSelectionBox.getSelectedIndex();
@@ -27,6 +27,22 @@
<g:ListBox ui:field="leaderboardSelectionBox" />
</div>
</div>
<div ui:field="leaderboardAutoZoomDiv" class="{res.mainCss.grid}" style="padding-bottom:1em;">
<div class="{res.mediaCss.small2} {res.mediaCss.columns}">
<span>Leaderboard Auto-Zoom:</span>
</div>
<div class="{res.mediaCss.small2} {res.mediaCss.columns}">
<g:CheckBox ui:field="leaderboardAutoZoomBox" />
</div>
</div>
<div ui:field="leaderboardZoomDiv" class="{res.mainCss.grid}" style="padding-bottom:1em;">
<div class="{res.mediaCss.small2} {res.mediaCss.columns}">
<span>Leaderboard Zoom-Factor:</span>
</div>
<div class="{res.mediaCss.small2} {res.mediaCss.columns}">
<g:TextBox ui:field="leaderboardZoomBox" />
</div>
</div>
<div class="{res.mainCss.grid}">
<div class="{res.mediaCss.small2} {res.mediaCss.columns}">
&nbsp;
@@ -0,0 +1,61 @@
package com.sap.sailing.gwt.common.client;
import com.google.gwt.dom.client.Style;
public class CSS3Util {
public static void setProperty(Style style, String baseCamelCasePropertyName, String value) {
for (String browserTypePrefix : getBrowserTypePrefixes()) {
style.setProperty(getBrowserSpecificPropertyName(browserTypePrefix, baseCamelCasePropertyName), value);
}
}
public static void setDashedProperty(Style style, String baseCamelCasePropertyName, String value) {
for (String browserTypePrefix : getBrowserTypePrefixes()) {
style.setProperty(getBrowserSpecificDashedPropertyName(browserTypePrefix, baseCamelCasePropertyName), value);
}
}
/**
* @return the prefixes required for new CSS3-style elements such as "transition" or "@keyframe", including the
* empty string, "moz" and "webkit" as well as others
*/
private static String[] getBrowserTypePrefixes() {
return new String[] { "", /* Firefox */ "moz", /* IE */ "ms", /* Opera */ "o", /* Chrome and Mobile */ "webkit" };
}
/**
* Converts something like "transformOrigin" to "-<code>browserType</code>-transform-origin"
*
* @param browserType
* a browser type string as received from {@link #getBrowserTypePrefixes()}. If empty or null, the
* original property name is returned unchanged
* @param camelCaseString
* the original camel-cased property name, such as "transformOrigin"
*/
public static String getBrowserSpecificDashedPropertyName(String browserType, String camelCaseString) {
StringBuilder result = new StringBuilder();
if (browserType != null && !browserType.isEmpty()) {
result.append('-');
result.append(browserType);
result.append('-');
}
for (int i=0; i<camelCaseString.length(); i++) {
final char c = camelCaseString.charAt(i);
if (Character.isUpperCase(c)) {
result.append('-');
}
result.append(Character.toLowerCase(c));
}
return result.toString();
}
public static String getBrowserSpecificPropertyName(String browserType, String basePropertyName) {
final String result;
if (browserType == null || browserType.isEmpty()) {
result = basePropertyName;
} else {
result = browserType+basePropertyName.substring(0, 1).toUpperCase()+basePropertyName.substring(1);
}
return result;
}
}