mapcomplete/UI/AddButton.ts

147 lines
4.7 KiB
TypeScript
Raw Normal View History

2020-06-24 00:35:19 +02:00
import {UIEventSource} from "./UIEventSource";
import {UIElement} from "./UIElement";
import {Basemap} from "../Logic/Basemap";
import {Changes} from "../Logic/Changes";
import L from "leaflet";
import {Tag} from "../Logic/TagsFilter";
import {FilteredLayer} from "../Logic/FilteredLayer";
export class AddButton extends UIElement {
public curentAddSelection: UIEventSource<string> = new UIEventSource<string>("");
private zoomlevel: UIEventSource<{ zoom: number }>;
private readonly SELECTING_POI = "selecting_POI";
private readonly PLACING_POI = "placing_POI";
private changes: Changes;
/*State is one of:
* "": the default stated
* "select_POI": show a 'select which POI to add' query (skipped if only one option exists)
* "placing_point": shown while adding a point
* ""
*/
private state: UIEventSource<string> = new UIEventSource<string>("");
private _options: { name: string; icon: string; tags: Tag[]; layerToAddTo: FilteredLayer }[];
constructor(
basemap: Basemap,
changes: Changes,
options: {
name: string,
icon: string,
tags: Tag[],
layerToAddTo: FilteredLayer
}[]) {
super(undefined);
this.zoomlevel = basemap.Location;
this.ListenTo(this.zoomlevel);
this._options = options;
this.ListenTo(this.curentAddSelection);
this.ListenTo(this.state);
this.state.setData(this.SELECTING_POI);
this.changes = changes;
const self = this;
basemap.map.on("click", function (e) {
const location = e.latlng;
console.log("Clicked at ", location)
self.HandleClick(location.lat, location.lng)
}
);
basemap.map.on("mousemove", function(){
if (self.state.data === self.PLACING_POI) {
2020-06-29 03:12:44 +02:00
let icon = "crosshair";
2020-06-24 00:35:19 +02:00
for (const option of self._options) {
if (option.name === self.curentAddSelection.data && option.icon !== undefined) {
icon = 'url("' + option.icon + '") 32 32 ,crosshair';
console.log("Cursor icon: ", icon)
}
}
document.getElementById('leafletDiv').style.cursor = icon;
} else {
// @ts-ignore
document.getElementById('leafletDiv').style.cursor = '';
}
});
}
private HandleClick(lat: number, lon: number): void {
this.state.setData(this.SELECTING_POI);
console.log("Handling click", lat, lon, this.curentAddSelection.data);
for (const option of this._options) {
if (this.curentAddSelection.data === option.name) {
console.log("PLACING a ", option);
let feature = this.changes.createElement(option.tags, lat, lon);
option.layerToAddTo.AddNewElement(feature);
return;
}
}
}
protected InnerRender(): string {
if (this.zoomlevel.data.zoom < 19) {
return "Zoom in om een punt toe te voegen"
}
if (this.state.data === this.SELECTING_POI) {
var html = "<form>";
for (const option of this._options) {
// <button type='button'> looks SO retarded
// the default type of button is 'submit', which performs a POST and page reload
html += "<button type='button' class='addPOIoption' value='" + option.name + "'>Voeg een " + option.name + " toe</button><br/>";
}
html += "</form>";
return html;
}
if (this.state.data === this.PLACING_POI) {
return "<div id='clickOnMapInstruction'>Klik op de kaart om een nieuw punt toe te voegen<div>" +
"<div id='cancelInstruction'>Klik hier om toevoegen te annuleren</div>"
}
if (this.curentAddSelection.data === "") {
return "<span onclick>Voeg een punt toe...</span>"
}
return "Annuleer";
}
InnerUpdate(htmlElement: HTMLElement) {
const self = this;
htmlElement.onclick = function (event) {
if(event.consumed){
return;
}
if (self.state.data === self.PLACING_POI) {
self.state.setData(self.SELECTING_POI);
}
}
const buttons = htmlElement.getElementsByClassName('addPOIoption');
// @ts-ignore
for (const button of buttons) {
button.onclick = function (event) {
self.curentAddSelection.setData(button.value);
self.state.setData(self.PLACING_POI);
event.consumed = true;
}
}
}
}