mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-04-21 18:23:35 +00:00
208 lines
5.8 KiB
Python
208 lines
5.8 KiB
Python
# Copyright 2018-2022 Streamlit Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from typing import Optional, Tuple, Any, List
|
|
|
|
from streamlit import util
|
|
from streamlit.scriptrunner import get_script_run_ctx
|
|
|
|
|
|
def make_delta_path(
|
|
root_container: int, parent_path: Tuple[int, ...], index: int
|
|
) -> List[int]:
|
|
delta_path = [root_container]
|
|
delta_path.extend(parent_path)
|
|
delta_path.append(index)
|
|
return delta_path
|
|
|
|
|
|
def get_container_cursor(
|
|
root_container: Optional[int],
|
|
) -> Optional["RunningCursor"]:
|
|
"""Return the top-level RunningCursor for the given container.
|
|
This is the cursor that is used when user code calls something like
|
|
`st.foo` (which uses the main container) or `st.sidebar.foo` (which uses
|
|
the sidebar container).
|
|
"""
|
|
if root_container is None:
|
|
return None
|
|
|
|
ctx = get_script_run_ctx()
|
|
|
|
if ctx is None:
|
|
return None
|
|
|
|
if root_container in ctx.cursors:
|
|
return ctx.cursors[root_container]
|
|
|
|
cursor = RunningCursor(root_container=root_container)
|
|
ctx.cursors[root_container] = cursor
|
|
return cursor
|
|
|
|
|
|
class Cursor:
|
|
"""A pointer to a delta location in the app.
|
|
|
|
When adding an element to the app, you should always call
|
|
get_locked_cursor() on that element's respective Cursor.
|
|
"""
|
|
|
|
def __repr__(self) -> str:
|
|
return util.repr_(self)
|
|
|
|
@property
|
|
def root_container(self) -> int:
|
|
"""The top-level container this cursor lives within - either
|
|
RootContainer.MAIN or RootContainer.SIDEBAR."""
|
|
raise NotImplementedError()
|
|
|
|
@property
|
|
def parent_path(self) -> Tuple[int, ...]:
|
|
"""The cursor's parent's path within its container."""
|
|
raise NotImplementedError()
|
|
|
|
@property
|
|
def index(self) -> int:
|
|
"""The index of the Delta within its parent block."""
|
|
raise NotImplementedError()
|
|
|
|
@property
|
|
def delta_path(self) -> List[int]:
|
|
"""The complete path of the delta pointed to by this cursor - its
|
|
container, parent path, and index.
|
|
"""
|
|
return make_delta_path(self.root_container, self.parent_path, self.index)
|
|
|
|
@property
|
|
def is_locked(self) -> bool:
|
|
raise NotImplementedError()
|
|
|
|
def get_locked_cursor(self, **props) -> "LockedCursor":
|
|
raise NotImplementedError()
|
|
|
|
@property
|
|
def props(self) -> Any:
|
|
"""Other data in this cursor. This is a temporary measure that will go
|
|
away when we implement improved return values for elements.
|
|
|
|
This is only implemented in LockedCursor.
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
|
|
class RunningCursor(Cursor):
|
|
def __init__(self, root_container: int, parent_path: Tuple[int, ...] = ()):
|
|
"""A moving pointer to a delta location in the app.
|
|
|
|
RunningCursors auto-increment to the next available location when you
|
|
call get_locked_cursor() on them.
|
|
|
|
Parameters
|
|
----------
|
|
root_container: int
|
|
The root container this cursor lives in.
|
|
parent_path: tuple of ints
|
|
The full path of this cursor, consisting of the IDs of all ancestors.
|
|
The 0th item is the topmost ancestor.
|
|
|
|
"""
|
|
self._root_container = root_container
|
|
self._parent_path = parent_path
|
|
self._index = 0
|
|
|
|
@property
|
|
def root_container(self) -> int:
|
|
return self._root_container
|
|
|
|
@property
|
|
def parent_path(self) -> Tuple[int, ...]:
|
|
return self._parent_path
|
|
|
|
@property
|
|
def index(self) -> int:
|
|
return self._index
|
|
|
|
@property
|
|
def is_locked(self) -> bool:
|
|
return False
|
|
|
|
def get_locked_cursor(self, **props) -> "LockedCursor":
|
|
locked_cursor = LockedCursor(
|
|
root_container=self._root_container,
|
|
parent_path=self._parent_path,
|
|
index=self._index,
|
|
**props,
|
|
)
|
|
|
|
self._index += 1
|
|
|
|
return locked_cursor
|
|
|
|
|
|
class LockedCursor(Cursor):
|
|
def __init__(
|
|
self,
|
|
root_container: int,
|
|
parent_path: Tuple[int, ...] = (),
|
|
index: int = 0,
|
|
**props,
|
|
):
|
|
"""A locked pointer to a location in the app.
|
|
|
|
LockedCursors always point to the same location, even when you call
|
|
get_locked_cursor() on them.
|
|
|
|
Parameters
|
|
----------
|
|
root_container: int
|
|
The root container this cursor lives in.
|
|
parent_path: tuple of ints
|
|
The full path of this cursor, consisting of the IDs of all ancestors. The
|
|
0th item is the topmost ancestor.
|
|
index: int
|
|
**props: any
|
|
Anything else you want to store in this cursor. This is a temporary
|
|
measure that will go away when we implement improved return values
|
|
for elements.
|
|
|
|
"""
|
|
self._root_container = root_container
|
|
self._index = index
|
|
self._parent_path = parent_path
|
|
self._props = props
|
|
|
|
@property
|
|
def root_container(self) -> int:
|
|
return self._root_container
|
|
|
|
@property
|
|
def parent_path(self) -> Tuple[int, ...]:
|
|
return self._parent_path
|
|
|
|
@property
|
|
def index(self) -> int:
|
|
return self._index
|
|
|
|
@property
|
|
def is_locked(self) -> bool:
|
|
return True
|
|
|
|
def get_locked_cursor(self, **props) -> "LockedCursor":
|
|
self._props = props
|
|
return self
|
|
|
|
@property
|
|
def props(self) -> Any:
|
|
return self._props
|