WLeafletMap::WidgetMarker.setAnchorPoint creates new divs

Added by Ulf Johnsson 7 months ago

Hi!
I have an issue when using WLeafletMap::WidgetMarker.setAnchorPoint().
I would seem that each time I call setAnchorPoint a new div is created?

Following example illustrates the issue:

class Application : public Wt::WApplication
{
public:
    Application(const Wt::WEnvironment &enviorment) : Wt::WApplication(enviorment) {}

    /***************************************************************/
    void initialize()
    {
        WApplication::initialize();

        root()->resize(800, 600);
        root()->decorationStyle().setBackgroundColor(Wt::green);

        Wt::WLeafletMap *map = new Wt::WLeafletMap(root());
        map->resize(500, 400);

        Wt::Json::Object options;
        options["maxZoom"] = 20;
        options["attribution"] = "&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors";
        map->addTileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", options);

        map->setZoomLevel(14);
        map->panTo(Wt::WLeafletMap::Coordinate(55.6406, 13.2162));

        Wt::Json::Object _options;
        _options["zoomControl"] = false;
        map->setOptions(_options);

        moveBtn = new Wt::WPushButton("move w+20", root());
        moveBtn->clicked().connect(this, &DumbApplication::moveAnchor);

        widgetMarker = new Wt::WLeafletMap::WidgetMarker(Wt::WLeafletMap::Coordinate(55.6406, 13.2), moveBtn);
        map->addMarker(widgetMarker);
        widgetMarker->setAnchorPoint(anchorX = 0, 0);
    }

    void moveAnchor()
    {
        widgetMarker->setAnchorPoint(anchorX -= 20, 0);
    }

    int anchorX;
    Wt::WPushButton *moveBtn;
    Wt::WLeafletMap::WidgetMarker *widgetMarker;
};

This is what the application looks like when it starts:

This is what happens after I click the button:

after_click.png (161 KB)

before_click.png (155 KB)


Replies (16)

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 7 months ago

I see. The problem is that the BIT_OPTIONS_CHANGED flag is not being reset, and this causes the map's JavaScript object to be recreated every time.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 7 months ago

I pushed the fix to master. The fix should probably also eventually end up in 4.2.1. I'll make a note of that.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Ulf Johnsson 7 months ago

Excellent, thanks.
Could you also push the fix to Wt3, seems like a pretty small fix?
We are using Wt3 and do not have the possibility to port our application to Wt4 right now.
BR, Ulf.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 7 months ago

You're right, it should be fixed for Wt 3, too. I also pushed that fix on the wt3 branch.

In case you're not aware, I actually just announced Wt 3 EOL on the blog. We will discontinue Wt 3 in 2021. For now, we'll still be making Wt 3 releases, though.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Ulf Johnsson 7 months ago

Thanks.
We are in the process of migrating to Wt4, and EOL of Wt3 is certainly a good reason to do so.

BR, Ulf.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Ulf Johnsson 7 months ago

Hi again,
I noticed a similar problem when calling Wt::WLeafletMap::WidgetMarker.move(). Will this patch also fix that problem?

BR, Ulf.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Ulf Johnsson 7 months ago

I noticed another problem.
Setting map-options after markers "breaks" the markers, I do not know if this is related to previous issues.
It would seem the entire map and all its <div> are recreated when setting mapoptions.
In the example below you will notice if you first click the w+20 button it will make the map wider, if you then click the toggle options button the w+20 button will stop working.

class Application : public Wt::WApplication
{
public:
    Application (const Wt::WEnvironment &enviorment) : Wt::WApplication(enviorment) {}

    /***************************************************************/
    void initialize()
    {
        WApplication::initialize();

        root()->resize(600, 400);
        root()->decorationStyle().setBackgroundColor(Wt::green);

        map = new Wt::WLeafletMap(root());
        map->resize(500, 300);

        Wt::Json::Object options;
        options["maxZoom"] = 20;
        options["attribution"] = "&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors";
        map->addTileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", options);

        map->setZoomLevel(14);
        map->panTo(Wt::WLeafletMap::Coordinate(55.6406, 13.2162));

        Wt::Json::Object _options;
        _options["zoomControl"] = false;
        _options["doubleClickZoom"] = false;
        _options["zoomAnimation"] = false;
        _options["fadeAnimation"] = false;
        _options["boxZoom"] = false;
        _options["keyboard"] = false;
        _options["dragging"] = false;
        map->setOptions(_options);

        moveBtn = new Wt::WPushButton("w+20", root());
        moveBtn->clicked().connect(this, &Application::widerMap);

        Wt::WPushButton *toggleBtn = new Wt::WPushButton("toggle options", root());
        toggleBtn->clicked().connect(this, &Application::toggle);

        widgetMarker = new Wt::WLeafletMap::WidgetMarker(Wt::WLeafletMap::Coordinate(55.6406, 13.2), moveBtn);
        map->addMarker(widgetMarker);
        widgetMarker->setAnchorPoint(anchorX = 0, 0);
    }

    void widerMap()
    {
        map->resize(map->width().value() + 50, map->height());
    }

    void toggle()
    {
        static bool value = true;
        value = !value;
        Wt::Json::Object _options;
        _options["zoomControl"] = false;
        _options["doubleClickZoom"] = false;
        _options["zoomAnimation"] = false;
        _options["fadeAnimation"] = false;
        _options["boxZoom"] = false;
        _options["keyboard"] = false;
        _options["dragging"] = false;
        _options["scrollWheelZoom"] = value;
        map->setOptions(_options);
    }

    int anchorX;
    Wt::WPushButton *moveBtn;
    Wt::WLeafletMap::WidgetMarker *widgetMarker;
    Wt::WLeafletMap *map;
};

BR, Ulf.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 6 months ago

I noticed a similar problem when calling Wt::WLeafletMap::WidgetMarker.move(). Will this patch also fix that problem?

I expect it will, yes.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 6 months ago

It would seem the entire map and all its <div> are recreated when setting mapoptions.

It is recreated, yes, as is detailed in its documentation: https://www.webtoolkit.eu/wt/doc/reference/html/classWt_1_1WLeafletMap.html#a1c2c19b8d81b28df613797c3f14dd0c4

I'll have to see about that w + 20 button.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 6 months ago

I just pushed the fix on all current branches (wt3, master, 3.5-release and 4.2-release), so you can check it out.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Ulf Johnsson 6 months ago

Awsome, thanks.
I will continue working on this in a week or so, I will return with feedback once I do so.

BR, Ulf.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 6 months ago

Hello Ulf,

Have you noticed any more issues after my fix?

Regards,
Roel

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Ulf Johnsson 6 months ago

Hi Roel.
It seems to work for my purposes now.

The issue that "connections" are removed after calling setOptions() still remains, which makes sense since the divs are recreated. But it wold be nice if the automaticaly could reestablish their connections.
I have however implemented a solution were I never call setOptions(), instead i use javascript to directly enable/disable controls in the map, and that seems to be working for me.

BR, Ulf.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 5 months ago

So any widgets you add to the leaflet map, they won't emit their signals anymore when you change the options? I don't think that's supposed to happen. It's supposed to still be the same widget so that's strange.

RE: WLeafletMap::WidgetMarker.setAnchorPoint creates new divs - Added by Roel Standaert 5 months ago

I see what's going wrong. The signal becomes unexposed. I pushed a fix.

(1-16/16)