Source code for sepal_ui.mapping.fullscreen_control

"""Customized control to toggle the fullscreen state of the map."""

from pathlib import Path
from typing import List, Optional

import ipyvuetify as v
from ipyleaflet import Map, WidgetControl
from IPython.display import Javascript, display

from sepal_ui.mapping.map_btn import MapBtn


[docs] class FullScreenControl(WidgetControl): ICONS: List[str] = ["fa-solid fa-expand", "fa-solid fa-compress"] "list: The icons that will be used to toggle between expand and compressed mode" METHODS: List[str] = ["embed", "fullscreen"] "list: The javascript methods name to be used to switch from expand to compress mode" zoomed: bool = False "bool: the current zoomed level: ``True`` for expanded and ``False`` for compressed" w_btn: Optional[v.Btn] = None "the btn to display on the map" template: Optional[v.VuetifyTemplate] = None "Embeds the 2 javascripts methods to change the rendering of the map"
[docs] def __init__( self, m: Map, fullscreen: bool = False, fullapp: bool = False, **kwargs ) -> None: """A custom Fullscreen Button ready to be embed in a map object. This button will force the display of the map in fullscreen mode. It should be used instead of the built-in ipyleaflet FullscreenControl if your map is embedding ipyvuetify widgets. I tends to solve the issue raised here: https://github.com/widgetti/ipyvuetify/issues/141. The idea is to fake the fullscreen display by forcing the map container to extend to the full extend of the screen without using a z-index superior to the ipyvuetify overlay. simply click on it and the map will automatically expand .. versionadded:: 2.7.0 Args: m: the map on which the mutated CSS will be applied (Only work with SepalMap as we are querying the _id) fullscreen: either the map should be displayed in fullscreen by default. default to false. fullapp: either or not the map will be used as the sole widget/tile of an application kwargs: any available arguments from a ipyleaflet WidgetControl """ # set the offset offset = "48px" if fullapp else "0px" # register the required zoom value self.zoomed = fullscreen # create a btn self.w_btn = MapBtn(self.ICONS[self.zoomed]) # overwrite the widget set in the kwargs (if any) kwargs["widget"] = self.w_btn kwargs.setdefault("position", "topleft") kwargs["transparent_bg"] = True # create the widget super().__init__(**kwargs) # add javascrip behaviour self.w_btn.on_event("click", self.toggle_fullscreen) # save the 2 fullscrenn js code in a table 0 for embedded and 1 for fullscreen js_dir = Path(__file__).parents[1] / "frontend/js" embed = (js_dir / "jupyter_embed.js").read_text() % m._id full = (js_dir / "jupyter_fullscreen.js").read_text() % (m._id, offset) # template with js behaviour # "jupyter_fullscreen" place the "leaflet-container element on the front screen # and expand it's display to the full screen # "jupyter_embed" reset all the changed parameter # both trigger the resize event to force the reload of the Tilelayers self.template = v.VuetifyTemplate( template=( "<script>{methods: {jupyter_embed(){%s}, jupyter_fullscreen(){%s}}}</script>" % (embed, full) ) ) display(self.template) # display the map in the requested default state js = full if self.zoomed else embed display(Javascript(js))
[docs] def toggle_fullscreen(self, *args) -> None: """Toggle fullscreen state. Toggle the fullscreen state of the map by sending the required javascript method, changing the w_btn icons and the zoomed state of the control. """ # change the zoom state self.zoomed = not self.zoomed # change button icon self.w_btn.children[0].children = [self.ICONS[self.zoomed]] # zoom self.template.send({"method": self.METHODS[self.zoomed], "args": []}) return