def build_form_widgets(self):
        """Build widgets to hold settings for edition."""
        ### create special list to hold widgets
        widgets = self.widgets = List2D()

        ### define an initial topleft relative to the
        ### topleft corner of the form 'rect'
        topleft = self.rect.move(5, 5).topleft

        ### instantiate a caption for the form

        caption_label = Object2D.from_surface(
            surface=(
                render_text(
                    text="Choose and start demonstration",
                    border_thickness=2,
                    border_color=(TEXT_SETTINGS["foreground_color"]),
                    **TEXT_SETTINGS,
                )
            ),
            coordinates_name="topleft",
            coordinates_value=topleft,
        )

        widgets.append(caption_label)

        ### update the topleft to a value a bit below
        ### the bottomleft corner of the widgets already
        ### in the versatile list
        topleft = widgets.rect.move(0, 20).bottomleft

        ### instantiate widgets for filtering/selecting
        ### demonstration

        ## label

        filter_select_label = Object2D.from_surface(
            surface=render_text(
                text="Filter/select a demonstration:", **TEXT_SETTINGS
            ),
            coordinates_name="topleft",
            coordinates_value=topleft,
        )

        widgets.append(filter_select_label)

        ## search box

        topleft = filter_select_label.rect.move(0, 5).bottomleft

        sb = self.search_box = SearchBox(
            value='',
            width=705,
            on_input = self.filter_demonstrations,
            coordinates_name='topleft',
            coordinates_value=topleft,
        )

        ## position search box a bit to the right

        sb_x_offset = 35
        sb.rect.x += sb_x_offset

        widgets.append(sb)

        ## create button to clear search box text

        self.clear_button = Button.from_text(
            text="Clear",
            command=partial(sb.set, ''),
            **BUTTON_SETTINGS,
        )

        draw_depth_finish(self.clear_button.image)

        self.clear_button.rect.midleft = sb.rect.move(5, 0).midright

        widgets.append(self.clear_button)


        ## list of available demonstrations

        # the compensate the sb_x_offset
        topleft = sb.rect.move(-sb_x_offset, 10).bottomleft

        # list box
        self.list_box = ListBox(
            items = DEMONSTRATIONS,
            selectable_hint='one',
            no_of_visible_lines=12,
            width=790,
            padding=5,
            coordinates_name = 'topleft',
            coordinates_value = topleft,
        )

        widgets.append(self.list_box)

        ### update the topleft to a value a bit below
        ### the bottomleft corner of the widgets already
        ### in the versatile list
        topleft = widgets.rect.move(0, 20).bottomleft

        ### create and store behaviour for exiting the form
        ### (equivalent to setting the 'running' flag to False)
        self.cancel = partial(setattr, self, "running", False)

        ### create, position and store form related buttons

        ## start button

        start_button = Button.from_text(
            text="Start demonstration",
            command=self.trigger_demonstration,
            **BUTTON_SETTINGS,
        )

        draw_depth_finish(start_button.image)

        start_button.rect.bottomright = self.rect.move(-10, -10).bottomright

        ## cancel button

        cancel_button = Button.from_text(
            text="Cancel",
            command=self.cancel,
            **BUTTON_SETTINGS,
        )

        draw_depth_finish(cancel_button.image)

        cancel_button.rect.midright = start_button.rect.move(-5, 0).midleft

        ## store
        widgets.extend((cancel_button, start_button))
Build widgets to hold settings for edition.
nodezator/editing/playback/demonstrate/__init__.py