import nanome
from nanome._internal.ui import _LayoutNode
from nanome.api.ui import Button, Slider, UIList, Mesh, Label, TextInput, Image, LoadingBar, Dropdown
from nanome.util import enums
from .io import LayoutNodeIO
[docs]class LayoutNode(_LayoutNode):
"""
| Class for hierarchical UI objects representing part of a Nanome menu.
| Layout nodes are used to create menus, by defining where one UI element should be placed relative to another.
| One LayoutNode can contain one interactive UI element as well as any number of child Layout Nodes.
:param name: Name of the node, used to identify it and find it later
:type name: :class:`str`
"""
PaddingTypes = nanome.util.enums.PaddingTypes
SizingTypes = nanome.util.enums.SizingTypes
LayoutTypes = nanome.util.enums.LayoutTypes
io = LayoutNodeIO()
def __init__(self, name="node"):
_LayoutNode.__init__(self, name)
self.io = LayoutNodeIO(self)
[docs] def clone(self):
return self._clone()
# region properties.
@property
def enabled(self):
"""
| Defines if layout node is visible.
| If disabled, it will not influence the menu layout.
:type: :class:`bool`
"""
return self._enabled
@enabled.setter
def enabled(self, value):
self._enabled = value
@property
def name(self):
"""
| Name of the node, used to identify it and find it later
:type: :class:`str`
"""
return self._name
@name.setter
def name(self, value):
self._name = value
@property
def padding_type(self):
"""
| The padding type of the LayoutNode.
:type: :class:`~nanome.util.enums.PaddingTypes`
"""
return self._padding_type
@padding_type.setter
def padding_type(self, value):
self._padding_type = value
@property
def layer(self):
"""
| The node layer. A node on layer 0 and another on layer 1 will be on different layouts, possibly overlapping
:type: :class:`int`
"""
return self._layer
@layer.setter
def layer(self, value):
self._layer = value
@property
def layout_orientation(self):
"""
| Defines if children node should be arranged vertically or horizontally
:type: :class:`~LayoutOrientation`
"""
return self._layout_orientation
@layout_orientation.setter
def layout_orientation(self, value):
self._layout_orientation = value
@property
def sizing_type(self):
"""
| Defines how the node size in the layout should be calculated
:type: :class:`~SizingTypes`
"""
return self._sizing_type
@sizing_type.setter
def sizing_type(self, value):
self._sizing_type = value
@property
def sizing_value(self):
"""
| Size of the node in its layout.
| Behavior is different depending of :attr:`~sizing_type`
:type: :class:`float`
"""
return self._sizing_value
@sizing_value.setter
def sizing_value(self, value):
self._sizing_value = value
@property
def forward_dist(self):
"""
| Sets the depth distance (towards camera) of a node, relative to its parent
:type: :class:`float`
"""
return self._forward_dist
@forward_dist.setter
def forward_dist(self, value):
self._forward_dist = value
@property
def padding(self):
return self._padding
@padding.setter
def padding(self, value):
self._padding = value
@property
def parent(self):
return self._parent
@parent.setter
def parent(self, value):
self._parent = value
# endregion
# region API functions
[docs] def find_node(self, name, recursively=True):
# type: (str, bool) -> LayoutNode
"""
| Checks child nodes for a node of the matching name.
| If "recursively" is True, this also checks all descending nodes.
:param name: Name of the node to find.
:type name: str
:return: LayoutNode with matching name
:rtype: :class:`~nanome.ui.LayoutNode`
"""
res = None
for child in self.get_children():
if name == child.name:
res = child
elif recursively:
res = child.find_node(name, True)
if res is not None:
break
return res
[docs] def find_ancestor(self, name):
if (self._parent is not None):
if (self._parent.name == name):
return self._parent
return self._parent.find_ancestor(name)
return None
[docs] def get_children(self):
return self._get_children()
@property
def children(self):
return self._children
@children.setter
def children(self, value):
self._children = value
@property
def content(self):
return self._content
@content.setter
def content(self, ui_content):
self._content = ui_content
[docs] def get_content(self):
return self.content
[docs] def set_content(self, ui_content):
self.content = ui_content
[docs] def remove_content(self):
self.content = None
[docs] def add_child(self, child_node):
self._add_child(child_node)
[docs] def remove_child(self, child_node):
self._remove_child(child_node)
[docs] def clear_children(self):
self._clear_children()
# endregion
# region API Shortcuts
[docs] def create_child_node(self, name=""):
child = LayoutNode(name)
self.add_child(child)
return child
[docs] def set_padding(self, left=None, right=None, top=None, down=None):
self.padding = (
left if left is not None else self.padding[0],
right if right is not None else self.padding[1],
top if top is not None else self.padding[2],
down if down is not None else self.padding[3]
)
[docs] def set_size_ratio(self, size):
self.sizing_type = self.SizingTypes.ratio
self.sizing_value = size
[docs] def set_size_fixed(self, size):
self.sizing_type = self.SizingTypes.fixed
self.sizing_value = size
[docs] def set_size_expand(self):
self.sizing_type = self.SizingTypes.expand
# endregion
# region Content adders
[docs] def add_new_toggle_switch(self, text=None):
# type: (str) -> Button
button = Button(text=text)
button.switch.active = True
button.outline.active = False
button.mesh.active = False
button.toggle_on_press = True
button.text.horizontal_align = nanome.util.enums.HorizAlignOptions.Left
self.set_content(button)
return button
[docs] def add_new_label(self, text=None):
# type: (str) -> Label
label = Label(text=text)
self.set_content(label)
return label
[docs] def add_new_text_input(self, placeholder_text=""):
# type: () -> TextInput
text_input = TextInput()
text_input.placeholder_text = placeholder_text
self.set_content(text_input)
return text_input
[docs] def add_new_slider(self, min_value=0, max_value=10, current_value=5):
# type: () -> Slider
slider = Slider(min_value, max_value, current_value)
self.set_content(slider)
return slider
[docs] def add_new_mesh(self):
# type: () -> Mesh
mesh = Mesh()
self.set_content(mesh)
return mesh
[docs] def add_new_image(self, file_path=""):
image = Image(file_path)
self.set_content(image)
return image
[docs] def add_new_loading_bar(self):
loading_bar = LoadingBar()
self.set_content(loading_bar)
return loading_bar
[docs] def add_new_list(self):
# type: () -> UIList
list_ = UIList()
self.set_content(list_)
return list_
[docs] def add_new_dropdown(self):
# type: () -> Dropdown
dropdown_ = Dropdown()
self.set_content(dropdown_)
return dropdown_
# endregion
LayoutNode.io._setup_addon(LayoutNode)
_LayoutNode._create = LayoutNode