-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ensure toolbar buttons toggle widgets, and turn off when widgets are closed. #1763
Conversation
- Note that closing the tool directly does not update the toolbar button yet.
@sufyanAbbasi Thanks a lot for the great improvement. I am on travel today. I might not be able to review this until tonight or tomorrow. If @naschmitz or @bengalin has time, please feel free to review and merge it. |
@sufyanAbbasi – Currently reviewing the PR. How difficult would it be to update this PR to support multiple widgets being open at the same time? It's a common use case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Some nits, but approach looks good. It would be nice to do away with the toggle_off
attr if possible.
geemap/toolbar.py
Outdated
@@ -15,9 +15,11 @@ | |||
import ipyevents | |||
import ipyleaflet | |||
import ipywidgets as widgets | |||
|
|||
from ipywidgets.widgets import Widget |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: ipywidgets.widgets.Widget
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed and using widgets.Widget
below.
geemap/toolbar.py
Outdated
reset: bool = True | ||
control: Optional[Widget] = None | ||
toggle_button: Any = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional[ipywidgets.ToggleButton]
? Will this ever be something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, done.
geemap/core.py
Outdated
if selected: | ||
common.open_url("https://geemap.org") | ||
|
||
def _toolbar_main_tools(self) -> List[toolbar.Toolbar.Item]: | ||
@toolbar._cleanup_toolbar_item | ||
def inspector_tool_callback(map, _, item): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Could you add type annotations here + call del on the unused properties?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
if selected: | ||
common.open_url("https://geemap.org") | ||
|
||
def _toolbar_main_tools(self) -> List[toolbar.Toolbar.Item]: | ||
@toolbar._cleanup_toolbar_item | ||
def inspector_tool_callback(map, _, item): | ||
map.add("inspector") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if add
should return the ipywidget widget that was just added... It would make it quite a bit more useful. We'd be changing the public API, but I'm okay with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be a great addition to the API, but I'm less inclined to make the change in this PR.
geemap/core.py
Outdated
del host_map # Unused. | ||
del item # Unused. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: del host_map, item # Unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
geemap/toolbar.py
Outdated
@@ -163,7 +179,7 @@ def _reset_others(self, current): | |||
if other is not current: | |||
other.value = False | |||
|
|||
def _toggle_callback(self, m, selected): | |||
def _toggle_callback(self, m, selected, _): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: _toggle_callback(self, m, selected, item)
and then call del item # Unused.
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
if hasattr(m, "pixel_values"): | ||
delattr(m, "pixel_values") | ||
if hasattr(m, "marker_cluster"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't it necessary to delattr pixel_values
anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See line 414, I think this is a diff artifact.
geemap/toolbar.py
Outdated
@@ -587,6 +585,7 @@ def handle_interaction(**kwargs): | |||
toolbar_control = ipyleaflet.WidgetControl( | |||
widget=toolbar_widget, position="topright" | |||
) | |||
setattr(toolbar_control, "cleanup", cleanup) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toolbar_control.cleanup = cleanup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and below.
geemap/toolbar.py
Outdated
close_button.observe(close_btn_click, "value") | ||
|
||
toolbar_button.value = True | ||
if m is not None: | ||
toolbar_control = ipyleaflet.WidgetControl( | ||
widget=toolbar_widget, position="topright" | ||
) | ||
|
||
setattr(toolbar_control, "cleanup", cleanup) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toolbar_control.cleanup = cleanup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and below.
geemap/toolbar.py
Outdated
toolbar_button.value = True | ||
if m is not None: | ||
toolbar_control = ipyleaflet.WidgetControl( | ||
widget=toolbar_widget, position="topright" | ||
) | ||
setattr(toolbar_control, "cleanup", cleanup) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here and some other place in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and below.
Very easy, just removed two lines in |
Objective
To design a scalable system to make it easy to implement new toolbar items that clean themselves up when closed or un-toggled.
Implementation
cleanup
property that is a method that safely removes it from the map and clean up any state. Then, the decorator modifies thecleanup
property to also call thetoggle_off
method which turns off the respective toggle in the toolbar. Then, when the "close" button is clicked, the callback uses the modified version of thecleanup
so that cleanup and toggle off both occur.Backwards Incompatibility Notes
map.tool_control
property is shared amongst widgets.Tested
Added unit tests to test cleanup behaviors and tested in Jupyter-Lab and Colab: https://colab.research.google.com/drive/1HHQomXhy-vS68qiMu6AOhDmrsLq6OZwe#scrollTo=6-4Mn2sAFNrO