Skip to content

Commit

Permalink
Merge pull request #1983 from gee-community/spinner
Browse files Browse the repository at this point in the history
Add layer loading spinner and remove layer button
  • Loading branch information
naschmitz authored Jun 12, 2024
2 parents d1a83ea + c71d646 commit 7bf4e3d
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 4 deletions.
106 changes: 102 additions & 4 deletions geemap/map_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from IPython.core.display import HTML, display

import ee
import ipyevents
import ipytree
import ipywidgets

Expand Down Expand Up @@ -765,7 +766,7 @@ def close_button_hidden(self, value):
def refresh_layers(self):
"""Recreates all the layer widgets."""
toggle_all_layout = ipywidgets.Layout(
height="18px", width="30ex", padding="0px 8px 25px 8px"
height="18px", width="30ex", padding="0px 4px 25px 4px"
)
toggle_all_checkbox = ipywidgets.Checkbox(
value=False,
Expand Down Expand Up @@ -809,7 +810,7 @@ def _render_layer_row(self, layer):
max=1,
step=0.01,
readout=False,
layout=ipywidgets.Layout(width="80px"),
layout=ipywidgets.Layout(width="70px", padding="0px 3px 0px 0px"),
)
opacity_slider.observe(
lambda change: self._on_layer_opacity_changed(change, layer), "value"
Expand All @@ -822,10 +823,107 @@ def _render_layer_row(self, layer):
)
settings_button.on_click(self._on_layer_settings_click)

spinner = ipywidgets.Button(
icon="times",
layout=ipywidgets.Layout(width="25px", height="25px", padding="0px"),
tooltip="Loaded",
)

def loading_change(change):
if change["new"]:
spinner.tooltip = "Loading ..."
spinner.icon = "spinner spin lg"
else:
spinner.tooltip = "Loaded"
spinner.icon = "times"

layer.observe(loading_change, "loading")

spinner_event = ipyevents.Event(
source=spinner, watched_events=["mouseenter", "mouseleave"]
)

def handle_spinner_event(event):
if event["type"] == "mouseenter":
spinner.icon = "times"
elif event["type"] == "mouseleave":
if layer.loading:
spinner.icon = "spinner spin lg"
else:
spinner.icon = "times"

spinner_event.on_dom_event(handle_spinner_event)

def remove_layer_click(_):
self._on_layer_remove_click(layer)

spinner.on_click(remove_layer_click)

return ipywidgets.HBox(
[visibility_checkbox, settings_button, opacity_slider],
layout=ipywidgets.Layout(padding="0px 8px 0px 8px"),
[
visibility_checkbox,
opacity_slider,
settings_button,
spinner,
],
layout=ipywidgets.Layout(padding="0px 4px 0px 4px"),
)

def _find_layer_row_index(self, layer):
for index, child in enumerate(self._toolbar_footer.children[1:]):
if child.children[0].description == layer.name:
return index + 1
return -1

def _remove_confirm_widget(self):
for index, child in enumerate(self._toolbar_footer.children[1:]):
if child.children[0].value == "Remove layer?":
self._toolbar_footer.children = (
self._toolbar_footer.children[: index + 1]
+ self._toolbar_footer.children[index + 2 :]
)
break

def _on_layer_remove_click(self, layer):
self._remove_confirm_widget()

label = ipywidgets.Label(
"Remove layer?",
layout=ipywidgets.Layout(padding="0px 4px 0px 4px"),
)
yes_button = ipywidgets.Button(
description="Yes",
button_style="primary",
)
yes_button.layout.width = "86px"
no_button = ipywidgets.Button(
description="No",
button_style="primary",
)
no_button.layout.width = "86px"

confirm_widget = ipywidgets.HBox(
[label, yes_button, no_button], layout=ipywidgets.Layout(width="284px")
)

layer_row_index = self._find_layer_row_index(layer)

self._toolbar_footer.children = (
list(self._toolbar_footer.children[: layer_row_index + 1])
+ [confirm_widget]
+ list(self._toolbar_footer.children[layer_row_index + 1 :])
)

def on_yes_button_click(_):
self._host_map.remove_layer(layer)
self._remove_confirm_widget()

yes_button.on_click(on_yes_button_click)

def on_no_button_click(_):
self._remove_confirm_widget()

no_button.on_click(on_no_button_click)

def _compute_layer_opacity(self, layer):
if layer in self._host_map.geojson_layers:
Expand Down
6 changes: 6 additions & 0 deletions tests/fake_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ def __init__(self, name="test-layer", visible=True, opacity=1.0):
self.visible = visible
self.opacity = opacity

def observe(self, func, names):
pass


class FakeTileLayer:
def __init__(self, name="test-layer", visible=True, opacity=1.0):
Expand All @@ -128,3 +131,6 @@ def __init__(self, name="test-layer", visible=True, style=None):
self.name = name
self.visible = visible
self.style = style or {}

def observe(self, func, names):
pass

0 comments on commit 7bf4e3d

Please sign in to comment.