Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 137 additions & 34 deletions leafmap/maplibregl.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@

basemaps = Box(xyz_to_leaflet(), frozen_box=True)

SIDEBAR_PANEL_BACKGROUND = "#ffffff"
SIDEBAR_PANEL_TEXT_COLOR = "#212121"
SIDEBAR_SCROLLBAR_STYLE = "scrollbar-color: #bdbdbd #f5f5f5; scrollbar-width: thin;"


class Map(MapWidget):
"""The Map class inherits from the MapWidget class of the maplibre.ipywidget module."""
Expand Down Expand Up @@ -553,7 +557,9 @@ def add_to_sidebar(
and self.add_floating_sidebar_flag
and not hasattr(self, "floating_sidebar_content_box")
):
self.floating_sidebar_content_box = widgets.VBox(children=[])
self.floating_sidebar_content_box = widgets.VBox(
children=[], layout=widgets.Layout(width="100%", overflow="hidden")
)
self._floating_sidebar_widgets = {}

# Check if floating sidebar is being used
Expand Down Expand Up @@ -5438,7 +5444,9 @@ def add_floating_sidebar(

# Initialize floating sidebar state
if not hasattr(self, "floating_sidebar_content_box"):
self.floating_sidebar_content_box = widgets.VBox(children=[])
self.floating_sidebar_content_box = widgets.VBox(
children=[], layout=widgets.Layout(width="100%", overflow="hidden")
)

if not hasattr(self, "_floating_sidebar_widgets"):
self._floating_sidebar_widgets = {}
Expand All @@ -5449,25 +5457,39 @@ def add_floating_sidebar(
content_widgets.extend(sidebar_content)

# Create main sidebar box with layer manager and additional content
main_sidebar_box = widgets.VBox(children=content_widgets)
main_sidebar_box = widgets.VBox(
children=content_widgets,
layout=widgets.Layout(width="100%", overflow="hidden"),
)

# Create toggle button
toggle_icon = v.Icon(
children=["mdi-chevron-left"] if sidebar_visible else ["mdi-chevron-right"],
small=True,
style_=f"color: {SIDEBAR_PANEL_TEXT_COLOR};",
)
toggle_btn = v.Btn(
icon=True,
children=[toggle_icon],
style_="width: 22px; height: 22px; min-width: 22px; padding: 0;",
style_=(
f"width: 22px; height: 22px; min-width: 22px; padding: 0; "
f"color: {SIDEBAR_PANEL_TEXT_COLOR};"
),
)

# Create settings/wrench button
settings_icon = v.Icon(children=["mdi-wrench"], small=True)
settings_icon = v.Icon(
children=["mdi-wrench"],
small=True,
style_=f"color: {SIDEBAR_PANEL_TEXT_COLOR};",
)
settings_btn = v.Btn(
icon=True,
children=[settings_icon],
style_="width: 22px; height: 22px; min-width: 22px; padding: 0;",
style_=(
f"width: 22px; height: 22px; min-width: 22px; padding: 0; "
f"color: {SIDEBAR_PANEL_TEXT_COLOR};"
),
)
Comment thread
giswqs marked this conversation as resolved.

# Create header row with toggle and settings buttons
Expand Down Expand Up @@ -5503,7 +5525,7 @@ class SidebarState:
step=10,
description="Width:",
continuous_update=True,
layout=widgets.Layout(width="100%"),
layout=widgets.Layout(width="100%", min_width="0"),
)

# Width change handler
Expand All @@ -5518,8 +5540,10 @@ def on_width_change(change):
overflow-y: auto;
overflow-x: hidden;
z-index: 1000;
background-color: white;
background-color: {SIDEBAR_PANEL_BACKGROUND};
color: {SIDEBAR_PANEL_TEXT_COLOR};
border-radius: 4px;
{SIDEBAR_SCROLLBAR_STYLE}
"""

width_slider.observe(on_width_change, names="value")
Expand Down Expand Up @@ -5554,7 +5578,8 @@ def on_settings_click(widget, event, data):

# Combine main sidebar with dynamic content box for layer settings and other widgets
sidebar_box = widgets.VBox(
children=[main_sidebar_box, self.floating_sidebar_content_box]
children=[main_sidebar_box, self.floating_sidebar_content_box],
layout=widgets.Layout(width="100%", overflow="hidden"),
)

# Toggle function
Expand All @@ -5577,8 +5602,10 @@ def toggle_sidebar(widget, event, data):
overflow-y: auto;
overflow-x: hidden;
z-index: 1000;
background-color: white;
background-color: {SIDEBAR_PANEL_BACKGROUND};
color: {SIDEBAR_PANEL_TEXT_COLOR};
border-radius: 4px;
{SIDEBAR_SCROLLBAR_STYLE}
"""
else:
# Hide sidebar content, only show toggle button
Expand All @@ -5592,9 +5619,11 @@ def toggle_sidebar(widget, event, data):
max-height: none;
overflow: visible;
z-index: 1000;
background-color: white;
background-color: {SIDEBAR_PANEL_BACKGROUND};
color: {SIDEBAR_PANEL_TEXT_COLOR};
border-radius: 4px;
padding: 4px;
{SIDEBAR_SCROLLBAR_STYLE}
"""

toggle_btn.on_event("click", toggle_sidebar)
Expand All @@ -5612,8 +5641,10 @@ def toggle_sidebar(widget, event, data):
overflow-y: auto;
overflow-x: hidden;
z-index: 1000;
background-color: white;
background-color: {SIDEBAR_PANEL_BACKGROUND};
color: {SIDEBAR_PANEL_TEXT_COLOR};
border-radius: 4px;
{SIDEBAR_SCROLLBAR_STYLE}
"""
else:
initial_style = f"""
Expand All @@ -5624,9 +5655,11 @@ def toggle_sidebar(widget, event, data):
max-height: none;
overflow: visible;
z-index: 1000;
background-color: white;
background-color: {SIDEBAR_PANEL_BACKGROUND};
color: {SIDEBAR_PANEL_TEXT_COLOR};
border-radius: 4px;
padding: 4px;
{SIDEBAR_SCROLLBAR_STYLE}
"""

overlay = v.Card(
Expand Down Expand Up @@ -8166,27 +8199,36 @@ def __init__(
self.map_stack.children = [m]

# Sidebar content container
self.sidebar_content_box = widgets.VBox()
self.sidebar_content_box = widgets.VBox(
layout=widgets.Layout(width="100%", overflow="hidden")
)
if sidebar_content:
self.set_sidebar_content(sidebar_content)

# Toggle button
self.toggle_icon = v.Icon(
children=["mdi-chevron-right"] if sidebar_visible else ["mdi-chevron-left"]
children=["mdi-chevron-right"] if sidebar_visible else ["mdi-chevron-left"],
style_=f"color: {SIDEBAR_PANEL_TEXT_COLOR};",
)
self.toggle_btn = v.Btn(
icon=True,
children=[self.toggle_icon],
style_="width: 48px; height: 48px; min-width: 48px;",
style_=(
f"width: 48px; height: 48px; min-width: 48px; "
f"color: {SIDEBAR_PANEL_TEXT_COLOR};"
),
)
self.toggle_btn.on_event("click", self.toggle_sidebar)

# Settings icon
self.settings_icon = v.Icon(children=["mdi-wrench"])
self.settings_icon = v.Icon(
children=["mdi-wrench"],
style_=f"color: {SIDEBAR_PANEL_TEXT_COLOR};",
)
self.settings_btn = v.Btn(
icon=True,
children=[self.settings_icon],
style_="width: 36px; height: 36px;",
style_=f"width: 36px; height: 36px; color: {SIDEBAR_PANEL_TEXT_COLOR};",
)
self.settings_btn.on_event("click", self.toggle_width_slider)

Expand Down Expand Up @@ -10264,6 +10306,7 @@ def __init__(
close_icon: str = "mdi-close",
label="Layers",
background_color: str = "#f5f5f5",
text_color: str = SIDEBAR_PANEL_TEXT_COLOR,
groups: dict = None,
*args: Any,
**kwargs: Any,
Expand All @@ -10279,6 +10322,9 @@ def __init__(
close_icon (str): The icon for the close button. Defaults to "mdi-close".
label (str): The label for the layer manager. Defaults to "Layers".
background_color (str): The background color of the header. Defaults to "#f5f5f5".
text_color (str): The color used for header text and icons. Defaults to
``SIDEBAR_PANEL_TEXT_COLOR``. Override this when passing a darker
``background_color`` so the header stays readable.
groups (dict): A dictionary of layer groups, such as {"Group 1": ["layer1", "layer2"],
"Group 2": ["layer3", "layer4"]}. A group layer toggle will be created for each group.
Defaults to None.
Expand Down Expand Up @@ -10317,19 +10363,32 @@ def __init__(
icon=True,
small=True,
class_="ma-0",
style_="min-width: 24px; width: 24px;",
children=[v.Icon(children=[close_icon])],
style_=f"min-width: 24px; width: 24px; color: {text_color};",
children=[
v.Icon(
children=[close_icon],
style_=f"color: {text_color};",
)
],
)
close_btn.on_event("click", self._handle_close)

header = v.ExpansionPanelHeader(
style_=f"height: {height}; min-height: {height}; background-color: {background_color};",
style_=(
f"height: {height}; min-height: {height}; "
f"background-color: {background_color}; "
f"color: {text_color};"
),
Comment thread
giswqs marked this conversation as resolved.
children=[
v.Row(
align="center",
class_="d-flex flex-grow-1 align-center",
children=[
v.Icon(children=[layer_icon], class_="ml-1"),
v.Icon(
children=[layer_icon],
class_="ml-1",
style_=f"color: {text_color};",
),
v.Spacer(), # push title to center
v.Html(tag="span", children=[label], class_="text-subtitle-2"),
v.Spacer(), # push close to right
Expand All @@ -10341,16 +10400,26 @@ def __init__(
)

panel = v.ExpansionPanel(
style_=(
f"background-color: {SIDEBAR_PANEL_BACKGROUND}; "
f"color: {text_color}; "
f"overflow-x: hidden; {SIDEBAR_SCROLLBAR_STYLE}"
),
children=[
header,
v.ExpansionPanelContent(
style_=(
f"background-color: {SIDEBAR_PANEL_BACKGROUND}; "
f"color: {text_color}; "
f"overflow-x: hidden; {SIDEBAR_SCROLLBAR_STYLE}"
),
children=[
widgets.VBox(
[self.master_toggle, self.group_toggles, self.layers_box]
)
]
],
),
]
],
)

if expanded:
Expand Down Expand Up @@ -10392,8 +10461,8 @@ def build_layer_controls(self) -> None:

checkbox = widgets.Checkbox(value=visible, description=name, style=style)
checkbox.layout.flex = "1 1 auto"
checkbox.layout.max_width = "200px"
checkbox.layout.min_width = "120px"
checkbox.layout.min_width = "0"
checkbox.layout.overflow = "hidden"

slider = widgets.FloatSlider(
value=opacity,
Expand All @@ -10403,7 +10472,10 @@ def build_layer_controls(self) -> None:
readout=False,
tooltip="Change layer opacity",
layout=widgets.Layout(
flex="1 1 auto", min_width="120px", padding=padding
flex="0 0 150px",
width="150px",
min_width="100px",
padding=padding,
),
)

Expand Down Expand Up @@ -10557,6 +10629,7 @@ def __init__(
close_icon: str = "mdi-close",
label: str = "My Tools",
background_color: str = "#f5f5f5",
text_color: str = SIDEBAR_PANEL_TEXT_COLOR,
height: str = "40px",
expanded: bool = True,
host_map: Optional[Any] = None,
Expand All @@ -10571,14 +10644,19 @@ def __init__(
widget_icon (str): Icon for the header. See https://pictogrammers.github.io/@mdi/font/2.0.46/ for available icons.
close_icon (str): Icon for the close button. See https://pictogrammers.github.io/@mdi/font/2.0.46/ for available icons.
background_color (str): Background color of the header. Defaults to "#f5f5f5".
text_color (str): Color used for header text and icons. Defaults to
``SIDEBAR_PANEL_TEXT_COLOR``. Override this when passing a darker
``background_color`` so the header stays readable.
label (str): Text label for the header. Defaults to "My Tools".
height (str): Height of the header. Defaults to "40px".
expanded (bool): Whether the panel is expanded by default. Defaults to True.
*args (Any): Additional positional arguments for the parent class.
**kwargs (Any): Additional keyword arguments for the parent class.
"""
# Wrap content in a mutable VBox
self.content_box = widgets.VBox()
self.content_box = widgets.VBox(
layout=widgets.Layout(width="100%", overflow="hidden")
)
self.host_map = host_map
if widget:
if isinstance(widget, (list, tuple)):
Expand All @@ -10591,19 +10669,32 @@ def __init__(
icon=True,
small=True,
class_="ma-0",
style_="min-width: 24px; width: 24px;",
children=[v.Icon(children=[close_icon])],
style_=f"min-width: 24px; width: 24px; color: {text_color};",
children=[
v.Icon(
children=[close_icon],
style_=f"color: {text_color};",
)
],
)
close_btn.on_event("click", self._handle_close)

header = v.ExpansionPanelHeader(
style_=f"height: {height}; min-height: {height}; background-color: {background_color};",
style_=(
f"height: {height}; min-height: {height}; "
f"background-color: {background_color}; "
f"color: {text_color};"
),
Comment thread
giswqs marked this conversation as resolved.
children=[
v.Row(
align="center",
class_="d-flex flex-grow-1 align-center",
children=[
v.Icon(children=[widget_icon], class_="ml-1"),
v.Icon(
children=[widget_icon],
class_="ml-1",
style_=f"color: {text_color};",
),
v.Spacer(), # push title to center
v.Html(tag="span", children=[label], class_="text-subtitle-2"),
v.Spacer(), # push close to right
Expand All @@ -10615,10 +10706,22 @@ def __init__(
)

self.panel = v.ExpansionPanel(
style_=(
f"background-color: {SIDEBAR_PANEL_BACKGROUND}; "
f"color: {text_color}; "
f"overflow-x: hidden; {SIDEBAR_SCROLLBAR_STYLE}"
),
children=[
header,
v.ExpansionPanelContent(children=[self.content_box]),
]
v.ExpansionPanelContent(
style_=(
f"background-color: {SIDEBAR_PANEL_BACKGROUND}; "
f"color: {text_color}; "
f"overflow-x: hidden; {SIDEBAR_SCROLLBAR_STYLE}"
),
children=[self.content_box],
),
],
)

super().__init__(
Expand Down
Loading