Skip to content

Layout

Source code in core/treeclass.py
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
class Layout:
    def __init__(self, title: str = "", color: str = 'RANDOM', node = None):
        """ Node Frame

        All nodes created when a Layout is open are placed in this layout.
        If the 'color' argument is None, a random color is used

        If the node argument is None, the layout parent is the current layout, otherwise,
        the layout becomes the parent of the node and the previous parent of the node
        becomes the layout parent.

        ``` python
        with GeoNodes("Layout Demo"):

            with Layout("Some maths"):
                a = Integer(1) + 1

            geo = Mesh()
            geo.points.offset = (0, 0, a)

            geo.out()
        ```

        Parameters
        ----------
        title : str, optional
            Layout title default="".

        color : blender color, optional
            Layout color (randomly generated if None) default=None.

        node : Node, optional
            the layout is inserted as direct parent of the node default=None.

        """

        self.tree  = Tree.current_tree()
        self.bnode = self.tree._btree.nodes.new('NodeFrame')
        self.bnode.select = False
        self.transparent = title is None
        if not self.transparent:
            self.title = title

        self.color = self.tree._get_color(color)

        # Parent from the stack
        if len(self.tree._layouts):
            self.bnode.parent = self.tree._layouts[-1].bnode

        # There is a node to become the parent of
        if node is not None:

            # The node parent can override the current parent
            if node._bnode.parent is not None:
                self.bnode.parent = node._bnode.parent

            # Include the node
            self.include_node(node)

    def __str__(self):
        nodes = [n for n in self.tree._nodes.values() if n._bnode.parent == self.bnode]
        return f"<Layout '{self.title}', {len(nodes)} nodes>"

    # ====================================================================================================
    # Include a node
    # ====================================================================================================

    def include_node(self, node):
        if node._bnode.bl_idname not in ('NodeGroupOutput',):
            if self.transparent:
                node._bnode.parent = self.bnode.parent
            else:
                node._bnode.parent = self.bnode

    # ====================================================================================================
    # Title / color
    # ====================================================================================================

    @property
    def title(self):
        return self.bnode.label

    @title.setter
    def title(self, value):
        if value is not None:
            self.bnode.label = value

    @property
    def color(self):
        return self.bnode.color

    @color.setter
    def color(self, value):
        color = Tree._get_color(value)
        if color.is_none:
            self.bnode.use_custom_color = False
        else:
            self.bnode.use_custom_color = True
            self.bnode.color = color.bcolor

    # ====================================================================================================
    # Context
    # ====================================================================================================

    def push(self):
        self.tree._layouts.append(self)

    def pop(self):
        assert self.tree._layouts.pop() == self, f"Shouldn't happen with Layout '{self.title}'"

    def __enter__(self):
        self.push()
        return self

    def __exit__(self, type, exc_value, traceback):
        self.pop()

        if isinstance(exc_value, Break):
            return True

__init__(title='', color='RANDOM', node=None)

Node Frame

All nodes created when a Layout is open are placed in this layout. If the 'color' argument is None, a random color is used

If the node argument is None, the layout parent is the current layout, otherwise, the layout becomes the parent of the node and the previous parent of the node becomes the layout parent.

with GeoNodes("Layout Demo"):

    with Layout("Some maths"):
        a = Integer(1) + 1

    geo = Mesh()
    geo.points.offset = (0, 0, a)

    geo.out()

Parameters:

Name Type Description Default
title str

Layout title default="".

''
color blender color

Layout color (randomly generated if None) default=None.

'RANDOM'
node Node

the layout is inserted as direct parent of the node default=None.

None
Source code in core/treeclass.py
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
def __init__(self, title: str = "", color: str = 'RANDOM', node = None):
    """ Node Frame

    All nodes created when a Layout is open are placed in this layout.
    If the 'color' argument is None, a random color is used

    If the node argument is None, the layout parent is the current layout, otherwise,
    the layout becomes the parent of the node and the previous parent of the node
    becomes the layout parent.

    ``` python
    with GeoNodes("Layout Demo"):

        with Layout("Some maths"):
            a = Integer(1) + 1

        geo = Mesh()
        geo.points.offset = (0, 0, a)

        geo.out()
    ```

    Parameters
    ----------
    title : str, optional
        Layout title default="".

    color : blender color, optional
        Layout color (randomly generated if None) default=None.

    node : Node, optional
        the layout is inserted as direct parent of the node default=None.

    """

    self.tree  = Tree.current_tree()
    self.bnode = self.tree._btree.nodes.new('NodeFrame')
    self.bnode.select = False
    self.transparent = title is None
    if not self.transparent:
        self.title = title

    self.color = self.tree._get_color(color)

    # Parent from the stack
    if len(self.tree._layouts):
        self.bnode.parent = self.tree._layouts[-1].bnode

    # There is a node to become the parent of
    if node is not None:

        # The node parent can override the current parent
        if node._bnode.parent is not None:
            self.bnode.parent = node._bnode.parent

        # Include the node
        self.include_node(node)