UI: Maps top toolbar.

This commit is contained in:
Igor Kulikov 2025-01-31 19:32:18 +02:00
parent 9625985568
commit 80e83e0ff9
4 changed files with 113 additions and 17 deletions

View File

@ -276,16 +276,49 @@ class GroupsControl extends SidebarPaneControl<TB.GroupsControlOptions> {
} }
} }
class ToolbarButton extends L.Control<TB.ToolbarButtonOptions> { class TopToolbarButton {
private readonly button: JQuery<HTMLElement>;
private _onClick: (e: MouseEvent) => void;
constructor(private readonly options: TB.TopToolbarButtonOptions) {
const iconElement = $('<div class="tb-control-button-icon"></div>');
this.button = $("<a>")
.attr('class', 'tb-control-button tb-control-text-button')
.attr('href', '#')
.attr('role', 'button');
this.button.append(iconElement);
this.button.append(`<div class="tb-control-text">${this.options.title}</div>`);
this.loadIcon(iconElement);
this.button.on('click', (e) => {
e.stopPropagation();
e.preventDefault();
if (this._onClick) {
this._onClick(e.originalEvent);
}
});
}
onClick(onClick: (e: MouseEvent) => void): void {
this._onClick = onClick;
}
private loadIcon(iconElement: JQuery<HTMLElement>) {
// this.options.icon
}
getButtonElement(): JQuery<HTMLElement> {
return this.button;
}
}
class ToolbarButton {
private readonly id: string; private readonly id: string;
private readonly button: JQuery<HTMLElement>; private readonly button: JQuery<HTMLElement>;
private active = false; private active = false;
private disabled = false; private disabled = false;
constructor(options: TB.ToolbarButtonOptions) { constructor(private readonly options: TB.ToolbarButtonOptions) {
super(options);
this.id = options.id; this.id = options.id;
const buttonText = this.options.showText ? this.options.title : null; const buttonText = this.options.showText ? this.options.title : null;
this.button = $("<a>") this.button = $("<a>")
.attr('class', 'tb-control-button') .attr('class', 'tb-control-button')
@ -346,6 +379,25 @@ class ToolbarButton extends L.Control<TB.ToolbarButtonOptions> {
} }
} }
class TopToolbarControl {
private readonly toolbarElement: JQuery<HTMLElement>;
constructor(private readonly options: TB.TopToolbarControlOptions) {
const controlContainer = $('.leaflet-control-container', options.mapElement);
this.toolbarElement = $('<div class="tb-map-top-toolbar leaflet-top"></div>');
this.toolbarElement.appendTo(controlContainer);
}
toolbarButton(options: TB.TopToolbarButtonOptions): TopToolbarButton {
const button = new TopToolbarButton(options);
const buttonContainer = $('<div class="leaflet-bar leaflet-control"></div>');
button.getButtonElement().appendTo(buttonContainer);
buttonContainer.appendTo(this.toolbarElement);
return button;
}
}
class ToolbarControl extends L.Control<L.ControlOptions> { class ToolbarControl extends L.Control<L.ControlOptions> {
private buttonContainer: JQuery<HTMLElement>; private buttonContainer: JQuery<HTMLElement>;
@ -372,15 +424,14 @@ class ToolbarControl extends L.Control<L.ControlOptions> {
} }
class BottomToolbarControl extends L.Control<TB.BottomToolbarControlOptions> { class BottomToolbarControl {
private readonly buttonContainer: JQuery<HTMLElement>; private readonly buttonContainer: JQuery<HTMLElement>;
private toolbarButtons: ToolbarButton[] = []; private toolbarButtons: ToolbarButton[] = [];
container: HTMLElement; container: HTMLElement;
constructor(options: TB.BottomToolbarControlOptions) { constructor(private readonly options: TB.BottomToolbarControlOptions) {
super(options);
const controlContainer = $('.leaflet-control-container', options.mapElement); const controlContainer = $('.leaflet-control-container', options.mapElement);
const toolbar = $('<div class="tb-map-bottom-toolbar leaflet-bottom"></div>'); const toolbar = $('<div class="tb-map-bottom-toolbar leaflet-bottom"></div>');
toolbar.appendTo(controlContainer); toolbar.appendTo(controlContainer);
@ -389,10 +440,6 @@ class BottomToolbarControl extends L.Control<TB.BottomToolbarControlOptions> {
this.container = this.buttonContainer[0]; this.container = this.buttonContainer[0];
} }
addTo(map: L.Map): this {
return this;
}
getButton(id: string): ToolbarButton { getButton(id: string): ToolbarButton {
return this.toolbarButtons.find(b => b.getId() === id); return this.toolbarButtons.find(b => b.getId() === id);
} }
@ -452,6 +499,10 @@ const groups = (options: TB.GroupsControlOptions): GroupsControl => {
return new GroupsControl(options); return new GroupsControl(options);
} }
const topToolbar = (options: TB.TopToolbarControlOptions): TopToolbarControl => {
return new TopToolbarControl(options);
}
const toolbar = (options: L.ControlOptions): ToolbarControl => { const toolbar = (options: L.ControlOptions): ToolbarControl => {
return new ToolbarControl(options); return new ToolbarControl(options);
} }
@ -515,6 +566,8 @@ L.TB = L.TB || {
SidebarPaneControl, SidebarPaneControl,
LayersControl, LayersControl,
GroupsControl, GroupsControl,
TopToolbarButton,
TopToolbarControl,
ToolbarButton, ToolbarButton,
ToolbarControl, ToolbarControl,
BottomToolbarControl, BottomToolbarControl,
@ -522,6 +575,7 @@ L.TB = L.TB || {
sidebarPane, sidebarPane,
layers, layers,
groups, groups,
topToolbar,
toolbar, toolbar,
bottomToolbar, bottomToolbar,
TileLayer: { TileLayer: {

View File

@ -141,7 +141,7 @@
} }
} }
} }
.tb-map-bottom-toolbar { .tb-map-bottom-toolbar, .tb-map-top-toolbar {
left: 0; left: 0;
right: 0; right: 0;
display: flex; display: flex;

View File

@ -85,6 +85,7 @@ export abstract class TbMap<S extends BaseMapSettings> {
protected sidebar: L.TB.SidebarControl; protected sidebar: L.TB.SidebarControl;
protected customActionsToolbar: L.TB.TopToolbarControl;
protected editToolbar: L.TB.BottomToolbarControl; protected editToolbar: L.TB.BottomToolbarControl;
protected addMarkerButton: L.TB.ToolbarButton; protected addMarkerButton: L.TB.ToolbarButton;
@ -166,6 +167,7 @@ export abstract class TbMap<S extends BaseMapSettings> {
} }
this.setupDataLayers(); this.setupDataLayers();
this.setupEditMode(); this.setupEditMode();
this.setupCustomActions();
this.createdControlButtonTooltip(this.mapElement, ['topleft', 'bottomleft'].includes(this.settings.controlsPosition) ? 'right' : 'left'); this.createdControlButtonTooltip(this.mapElement, ['topleft', 'bottomleft'].includes(this.settings.controlsPosition) ? 'right' : 'left');
} }
@ -270,7 +272,7 @@ export abstract class TbMap<S extends BaseMapSettings> {
onClose: () => { onClose: () => {
return this.deselectItem(true); return this.deselectItem(true);
} }
}).addTo(this.map); });
this.map.on('click', () => { this.map.on('click', () => {
this.deselectItem(); this.deselectItem();
@ -349,6 +351,24 @@ export abstract class TbMap<S extends BaseMapSettings> {
} }
} }
private setupCustomActions() {
this.customActionsToolbar = L.TB.topToolbar({
mapElement: $(this.mapElement)
});
/*const customButton = this.customActionsToolbar.toolbarButton({
title: 'Super button',
icon: 'add'
});
this.customActionsToolbar.toolbarButton({
title: 'Super button 2',
icon: 'add'
});
customButton.onClick(e => {
console.log("Called!");
});*/
}
private placeMarker(e: MouseEvent, button: L.TB.ToolbarButton): void { private placeMarker(e: MouseEvent, button: L.TB.ToolbarButton): void {
this.placeItem(e, button, this.addMarkerDataLayers, this.placeItem(e, button, this.addMarkerDataLayers,
(entity) => { (entity) => {

View File

@ -89,7 +89,27 @@ declare module 'leaflet' {
constructor(options: GroupsControlOptions); constructor(options: GroupsControlOptions);
} }
interface ToolbarButtonOptions extends ControlOptions { interface TopToolbarButtonOptions {
icon: string;
iconColor?: string;
title: string;
}
class TopToolbarButton {
constructor(options: TopToolbarButtonOptions);
onClick(onClick: (e: MouseEvent) => void): void;
}
interface TopToolbarControlOptions {
mapElement: JQuery<HTMLElement>;
}
class TopToolbarControl {
constructor(options: TopToolbarControlOptions);
toolbarButton(options: TopToolbarButtonOptions): TopToolbarButton;
}
interface ToolbarButtonOptions {
id: string; id: string;
title: string; title: string;
click: (e: MouseEvent, button: ToolbarButton) => void; click: (e: MouseEvent, button: ToolbarButton) => void;
@ -97,7 +117,7 @@ declare module 'leaflet' {
showText?: boolean; showText?: boolean;
} }
class ToolbarButton extends Control<ToolbarButtonOptions>{ class ToolbarButton {
constructor(options: ToolbarButtonOptions); constructor(options: ToolbarButtonOptions);
setActive(active: boolean): void; setActive(active: boolean): void;
isActive(): boolean; isActive(): boolean;
@ -110,13 +130,13 @@ declare module 'leaflet' {
toolbarButton(options: ToolbarButtonOptions): ToolbarButton; toolbarButton(options: ToolbarButtonOptions): ToolbarButton;
} }
interface BottomToolbarControlOptions extends ControlOptions { interface BottomToolbarControlOptions {
mapElement: JQuery<HTMLElement>; mapElement: JQuery<HTMLElement>;
closeTitle: string; closeTitle: string;
onClose: () => boolean; onClose: () => boolean;
} }
class BottomToolbarControl extends Control<BottomToolbarControlOptions> { class BottomToolbarControl {
constructor(options: BottomToolbarControlOptions); constructor(options: BottomToolbarControlOptions);
getButton(id: string): ToolbarButton | undefined; getButton(id: string): ToolbarButton | undefined;
open(buttons: ToolbarButtonOptions[], showCloseButton?: boolean): void; open(buttons: ToolbarButtonOptions[], showCloseButton?: boolean): void;
@ -132,6 +152,8 @@ declare module 'leaflet' {
function groups(options: GroupsControlOptions): GroupsControl; function groups(options: GroupsControlOptions): GroupsControl;
function topToolbar(options: TopToolbarControlOptions): TopToolbarControl;
function toolbar(options: ControlOptions): ToolbarControl; function toolbar(options: ControlOptions): ToolbarControl;
function bottomToolbar(options: BottomToolbarControlOptions): BottomToolbarControl; function bottomToolbar(options: BottomToolbarControlOptions): BottomToolbarControl;