/*
* Copyright 2019 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { subclass, property } from "esri/core/accessorSupport/decorators";
import { tsx } from "esri/widgets/support/widget";
import Section from "./Section";
import Collection from "esri/core/Collection";
import Widget from "esri/widgets/Widget";
import FloorSelector from "../widgets/FloorSelector/FloorSelector";
import * as watchUtils from "esri/core/watchUtils";
import FeatureLayer from "esri/layers/FeatureLayer";
import Legend from "esri/widgets/Legend";
import PopupInfo from "../widgets/Popup/PopupInfo";
import * as appUtils from "../support/appUtils";
import Handles from "esri/core/Handles";
import AppState from "../AppState";
@subclass("legendWrapper")
class LegendWrapper extends Widget {
@property()
hide: boolean = true;
@property({ constructOnly: true })
appState: AppState;
@property()
legend: Legend;
constructor(args: { appState: AppState }, container: string) {
super(args as any);
}
postInitialize() {
this.legend = new Legend({
view: this.appState.view,
layerInfos: []
});
}
/*return (
*/
render() {
return (
{this.legend.render()}
);
}
}
@subclass("playButton")
class PlayButton extends Widget {
@property()
playing: boolean = false;
@property()
audioSrc: string;
@property({dependsOn: ["audioSrc"], readOnly: true })
get audio() {
return new Audio(this.audioSrc);
}
postInitialize() {
this.watch("audio", audio => {
audio.addEventListener("ended", () => {
audio.currentTime = 0;
this.playing = false;
});
});
}
render() {
const dynamicCss = {
"playing": this.playing
};
return (
);
}
onClick(event: Event) {
if (this.playing) {
this.playing = false;
this.audio.pause();
}
else {
this.audio.play();
this.playing = true;
}
}
}
interface FloorCtorArgs {
title: string;
subtitle: string;
content: (that: Floor) => any;
floor: number;
audio?: string;
}
interface FloorsSectionCtorArgs {
FloorSurface?: Collection;
}
interface FloorsSectionCtorArgs2 {
minFloor: number;
maxFloor: number;
}
@subclass("Floor")
export class Floor extends Widget {
@property()
title: string;
@property()
content: (that: this) => any;
@property()
subtitle: string;
@property()
floor = 1;
@property({aliasOf: "playButton.audioSrc"})
audio: string;
@property()
playButton = new PlayButton();
render() {
const audio = this.audio ? (Listen to the name of this floor {this.playButton.render()}
) : null;
return (
{this.content(this)}
{audio}
);
}
constructor(args: FloorCtorArgs) {
super(args as any);
}
activate() {
// put audio back to 0
this.playButton.audio.currentTime = 0;
}
}
@subclass("sections/FloorsSection")
export class FloorsSection extends Section {
@property()
title = "Floor by floor";
@property()
id = "FloorSurface";
@property({ aliasOf: "appState.BldgLevel"})
selectedFloor: number;
private oldDate: Date;
@property()
previousSelectedFloor: number;
@property()
floorSelector: FloorSelector;
@property()
legendWrapper: LegendWrapper;
@property()
layer: FeatureLayer;
@property({constructOnly: true })
layerNameForInfoPoint = appUtils.FLOOR_POINTS_LAYER_PREFIX;
@property({constructOnly: true })
layerNameForPicturePoint = appUtils.INTERNAL_INFOPOINTS_LAYER_PREFIX;
@property()
picturePointsLayer: FeatureLayer;
@property()
minFloor: number;
@property()
maxFloor: number;
private handles = new Handles();
@property({constructOnly: true})
FloorSurface: Collection;
render() {
const currentLevel = this.FloorSurface ? this.FloorSurface.getItemAt(this.selectedFloor) : null;
// const selectedFloor = this.selectedFloor === 0 ? "G" : this.selectedFloor;
const title = currentLevel ? this.selectedFloor === 0 ? ({currentLevel.title} ) : ({currentLevel.title} ) : null;
return currentLevel ? (
{/*
{selectedFloor} */}
{title}
{currentLevel.subtitle}
{currentLevel.render()}
) : null;
}
paneRight() {
const floorSelector = this.floorSelector ? this.floorSelector.render() : null;
return ({floorSelector}
);
}
constructor(args: FloorsSectionCtorArgs | FloorsSectionCtorArgs2) {
super(args as any);
}
postInitialize() {
watchUtils.whenOnce(this, "appState", () => {
this.legendWrapper = new LegendWrapper({
appState: this.appState
}, "floorLegend");
const floorSelectorCtorArgs = this.minFloor != null && this.maxFloor != null ? {
appState: this.appState,
minFloor: this.minFloor,
maxFloor: this.maxFloor
} : {
appState: this.appState
}
this.floorSelector = new FloorSelector(floorSelectorCtorArgs);
watchUtils.on(this, "appState.view.map.layers", "change", this.getExtraInfoLayers.bind(this));
watchUtils.init(this, "selectedFloor", (selectedFloor) => {
if (this.FloorSurface) {
this.FloorSurface.getItemAt(selectedFloor).activate();
}
// filter the picture and infoLayer:
if (this.layer) {
this.layer.definitionExpression = "level_id = " + selectedFloor;
}
if (this.picturePointsLayer) {
this.picturePointsLayer.definitionExpression = "level_id = " + selectedFloor;
}
});
});
}
onEnter() {
this.selectedFloor = 3;
if (this.FloorSurface) {
this.FloorSurface.getItemAt(this.selectedFloor).activate();
}
this.appState.view.environment.lighting.directShadowsEnabled = true;
this.appState.view.environment.lighting.ambientOcclusionEnabled = false;
this.oldDate = this.appState.view.environment.lighting.date;
this.appState.view.environment.lighting.date = new Date("Thu Aug 01 2019 13:00:00 GMT+0200 (Central European Summer Time)");
this.handles.add(this.appState.view.on("click", (event: any) => {
// the hitTest() checks to see if any graphics in the view
// intersect the given screen x, y coordinates
this.appState.view.hitTest(event)
.then((response) => {
const filtered = response.results.filter((result: any) => {
return result.graphic.layer === this.picturePointsLayer;
})[0];
if (filtered) {
this.appState.popupInfo = new PopupInfo({
image: filtered.graphic.attributes.url,
credit: filtered.graphic.attributes.title
});
}
});
}), "click");
this.legendWrapper.hide = !this.layer;
if (this.layer) {
this.layer.visible = true;
}
if (this.picturePointsLayer) {
this.picturePointsLayer.visible = true;
}
}
onLeave() {
this.handles.remove("click");
this.appState.view.environment.lighting.directShadowsEnabled = true;
this.appState.view.environment.lighting.ambientOcclusionEnabled = true;
this.appState.view.environment.lighting.date = this.oldDate;
this.legendWrapper.hide = true;
if (this.layer) {
this.layer.visible = false;
}
if (this.picturePointsLayer) {
this.picturePointsLayer.visible = false;
}
}
private getExtraInfoLayers() {
if (this.appState && this.appState.view.map.layers.length > 0) {
// Get the info points on the floors:
if (!this.layer) {
this.layer = appUtils.findLayer(this.appState.view.map.layers, this.layerNameForInfoPoint) as FeatureLayer;
if (this.layer) {
this.layer.visible = false;
this.legendWrapper.legend.layerInfos = [
{
layer: this.layer,
title: "Legend",
hideLayers: []
}
];
}
}
// Get extra pictures:
if (!this.picturePointsLayer) {
this.picturePointsLayer = appUtils.findLayer(this.appState.view.map.layers, this.layerNameForPicturePoint) as FeatureLayer;
if (this.picturePointsLayer) {
this.picturePointsLayer.visible = false;
this.picturePointsLayer.outFields = ["*"];
}
}
}
}
}