Gubancs / leaflet4vaadin

:herb: Leaflet4Vaadin :herb: provides a Java API for Leaflet, which is a popular map implementation, similar to Google Maps. Leaflet is lightweight and shines on mobile devices. Also it has an extensive set of add-ons, of which many are available for Vaadin too.
https://leaflet4vaadin.herokuapp.com/
Other
25 stars 19 forks source link

Add contextmenu plugin #26

Open easbar opened 4 years ago

easbar commented 4 years ago

Hey, thanks a lot for your nice work! I am trying to make the context menu https://github.com/aratcliffe/Leaflet.contextmenu plugin work with your add-on. In plain JavaScript it would probably be done like this:

var map = L.map('map', {
    contextmenu: true,
        contextmenuWidth: 140,
    contextmenuItems: [{
        text: 'some menu item',
        callback: doSomething
    });

So my first problem is that this requires extending the MapOptions interface (?!). But this does not seem to be right, because you probably do not want to add more methods to MapOptions every time a new leaflet plugin gets added and even more so it would be nice to use plugins without changing this add-on at all.

So another more flexible way would be adding the ContextMenu (which is implemented as a leaflet Handler: https://github.com/aratcliffe/Leaflet.contextmenu/blob/202b2ca8b302431f6d99ce93edf95684d4ee4422/src/Map.ContextMenu.js#L5) manually after creating the map:

var map = L.map('map');
L.setOptions(map, {
    contextmenu: true,
    contextmenuWidth: 140,
    contextmenuItems: [{
        text: 'some menu item',
        callback: doSomething
    }]
});
map.addHandler('contextmenu', L.Map.ContextMenu)

Can you give some advice how to do this for leaflet4vaadin? Generally, how should a Leaflet.Handler be added to the map? Btw if you are interested in adding context menu here I can also send a PR once I made it work.

Gubancs commented 4 years ago

Hi, Apologies for the Late Reply. This add-on currently doesn't support leaflet handlers, but I tried to make it flexible, so you can extend MapOptions if you want. If you implemented the context menu plugin and if you want you can send me a PR and I will merge it.

I did implement some plugins for example: Full-screen control plugin: https://leaflet4vaadin.herokuapp.com/plugins/fullscreen Heatmap plugin: https://leaflet4vaadin.herokuapp.com/plugins/heatmap Marker cluster plugin: https://leaflet4vaadin.herokuapp.com/plugins/markercluster

I have possible advice to implement this:

`MapOptions mapOptions = new DefaultMapOptions();

   //we need to implement a POJO that stores the options of the context menu plugin such us contextmenuWidth, contextmenuAnchor, etc.
    ContextMenuOptions contextMenuOptions = new ContextMenuOptions();
    contextMenuOptions.setContextmenuWidth(200);

   //we need to implement a POJO that stores the options of each menu item such as text, icon, callback, etc.
    List<ContextMenuItem> contexMenuItems = new ArrayList<>();
    contexMenuItems.add(new ContextMenuItem(text, icon, callback, ...);
    contexMenuItems.add(new ContextMenuItem(text, icon, callback, ...);

    //we need to add items to the context menu options
    contextMenuOptions.setContextmenuItems(contexMenuItems);

    //we need to implement an "apply" or "extend" method in map options which able to extends its properties dynamically. 
    mapOptions.apply(contextMenuOptions);

    LeafletMap leafletMap = new LeafletMap(mapOptions);
    leafletMap.setBaseUrl("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png");

    addToContent(buttons, leafletMap, pluginRepository);`

Currently the MapOptions serialized as JSON like this: { center: {lat: 17.0, lng: 12.0}, zoom: 12, .... } but it will look like this after we successfully implement the "apply" method: { center: {lat: 17.0, lng: 12.0}, zoom: 12, contextmenu: true, contextmenuWidth: 200 .... }