Skip to content

Commit 80f7d60

Browse files
Mike ProsserMike Prosser
authored andcommitted
flag checkboxes control
1 parent 2731464 commit 80f7d60

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

examples/all_types/all_types_panel.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
with col2:
2525
if isinstance(default_value, bool):
2626
st.checkbox(label=name, value=default_value, key=name)
27+
elif isinstance(default_value, Flag):
28+
nipanel.flag_checkboxes(panel, label=name, value=default_value, key=name)
2729
elif isinstance(default_value, Enum) and not isinstance(default_value, Flag):
2830
nipanel.enum_selectbox(panel, label=name, value=default_value, key=name)
2931
elif isinstance(default_value, int) and not isinstance(default_value, Flag):

src/nipanel/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
from importlib.metadata import version
44

55
from nipanel._panel import Panel
6-
from nipanel.controls._enum_selectbox import enum_selectbox
76
from nipanel._streamlit_panel import StreamlitPanel
87
from nipanel._streamlit_panel_initializer import create_panel, get_panel_accessor
98
from nipanel._streamlit_panel_value_accessor import StreamlitPanelValueAccessor
9+
from nipanel.controls._enum_selectbox import enum_selectbox
10+
from nipanel.controls._flag_checkboxes import flag_checkboxes
1011

1112
__all__ = [
1213
"create_panel",
1314
"enum_selectbox",
15+
"flag_checkboxes",
1416
"get_panel_accessor",
1517
"Panel",
1618
"StreamlitPanel",
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"""A set of checkboxes for selecting Flag enum values."""
2+
3+
from enum import Flag
4+
from typing import TypeVar
5+
6+
import streamlit as st
7+
8+
from nipanel._panel_value_accessor import PanelValueAccessor
9+
10+
T = TypeVar("T", bound=Flag)
11+
12+
13+
def flag_checkboxes(
14+
panel: PanelValueAccessor,
15+
label: str,
16+
value: T,
17+
key: str,
18+
disabled: bool = False,
19+
) -> T:
20+
"""Create a set of checkboxes for a Flag enum.
21+
22+
This will display a checkbox for each individual flag value in the enum. When checkboxes
23+
are selected or deselected, the combined Flag value will be stored in the panel under
24+
the specified key.
25+
26+
Args:
27+
panel: The panel
28+
label: Label to display above the checkboxes
29+
value: The default Flag enum value (also determines the specific Flag enum type)
30+
key: Key to use for storing the Flag value in the panel
31+
disabled: Whether the checkboxes should be disabled
32+
33+
Returns:
34+
The selected Flag enum value with all selected flags combined
35+
"""
36+
flag_type = type(value)
37+
if not issubclass(flag_type, Flag):
38+
raise TypeError(f"Expected a Flag enum type, got {type(value)}")
39+
40+
st.write(label + ":")
41+
42+
# Get all individual flag values (skip composite values and zero value)
43+
flag_values = [
44+
flag for flag in flag_type if flag.value & (flag.value - 1) == 0 and flag.value != 0
45+
]
46+
47+
# Create a container for flag checkboxes
48+
flag_container = st.container()
49+
selected_flags = flag_type(0) # Start with no flags
50+
51+
# If default value is set, use it as the initial state
52+
if value:
53+
selected_flags = value
54+
55+
# Create a checkbox for each flag
56+
for flag in flag_values:
57+
is_selected = bool(selected_flags & flag)
58+
if flag_container.checkbox(
59+
label=str(flag.name),
60+
value=is_selected,
61+
key=f"{key}_{flag.name}",
62+
disabled=disabled,
63+
):
64+
selected_flags |= flag
65+
else:
66+
selected_flags &= ~flag
67+
68+
# Store the selected flags in the panel
69+
panel.set_value(key, selected_flags)
70+
return selected_flags

0 commit comments

Comments
 (0)