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="Set and start system testing session",
                    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 recording title

        ## pick tests label

        label_text = (
            "Choose test cases to perform from the list of available ones"
            " by moving them to the list of chosen ones"
        )

        pick_cases_label = Object2D.from_surface(
            surface=render_text(
                text=label_text, **TEXT_SETTINGS
            ),
            coordinates_name="topleft",
            coordinates_value=topleft,
        )

        widgets.append(pick_cases_label)

        ### available tests list box

        ## label

        topleft = pick_cases_label.rect.move(0, 10).bottomleft

        available_cases_label = Object2D.from_surface(
            surface=render_text(
                text="Available test cases", **TEXT_SETTINGS
            ),
            coordinates_name="topleft",
            coordinates_value=topleft,
        )

        widgets.append(available_cases_label)

        ## listbox

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

        self.available_cases_listbox = ListBox(
            items = sorted(TEST_ID_TO_LABEL_TEXT.values()),
            selectable_hint='all',
            no_of_visible_lines=15,
            width=520,
            padding=5,
            coordinates_name = 'topleft',
            coordinates_value = topleft,
        )

        widgets.append(self.available_cases_listbox)

        ### chosen tests list box

        ## listbox

        topleft = self.available_cases_listbox.rect.move(20, 0).topright

        self.chosen_cases_listbox = ListBox(
            items = [],
            selectable_hint='all',
            no_of_visible_lines=15,
            width=520,
            padding=5,
            coordinates_name = 'topleft',
            coordinates_value = topleft,
        )

        widgets.append(self.chosen_cases_listbox)

        ## label

        bottomleft = self.chosen_cases_listbox.rect.move(0, -5).topleft

        chosen_cases_label = Object2D.from_surface(
            surface=render_text(
                text="Chosen test cases", **TEXT_SETTINGS
            ),
            coordinates_name="bottomleft",
            coordinates_value=bottomleft,
        )

        widgets.append(chosen_cases_label)


        ### test case selection/deselection buttons

        ## add button

        add_button_text_surf = (
            render_text(
                text="Add selected",
                **BUTTON_SETTINGS,
            )
        )

        add_button_surf = combine_surfaces(
            [ARROW_RIGHT_ICON, add_button_text_surf],
            retrieve_pos_from="midright",
            assign_pos_to="midleft",
            offset_pos_by=(0, 0),
            padding=2,
            background_color=BUTTON_BG,
        )

        draw_depth_finish(add_button_surf)

        topleft = self.available_cases_listbox.rect.move(5, 10).midbottom

        add_button = (

            Button(
                add_button_surf,
                command=self.add_selected,
                coordinates_name='topleft',
                coordinates_value=topleft,
            )

        )

        widgets.append(add_button)

        ## add all button

        add_all_button_text_surf = (
            render_text(
                text="Add all",
                **BUTTON_SETTINGS,
            )
        )

        add_all_button_surf = combine_surfaces(
            [ARROW_RIGHT_DOUBLE_ICON, add_all_button_text_surf],
            retrieve_pos_from="midright",
            assign_pos_to="midleft",
            offset_pos_by=(0, 0),
            padding=2,
            background_color=BUTTON_BG,
        )

        draw_depth_finish(add_all_button_surf)

        topright = self.available_cases_listbox.rect.move(-5, 10).midbottom

        add_all_button = (

            Button(
                add_all_button_surf,
                command=self.add_all,
                coordinates_name='topright',
                coordinates_value=topright,
            )

        )

        widgets.append(add_all_button)

        ## remove button

        remove_button_text_surf = (
            render_text(
                text="Remove selected",
                **BUTTON_SETTINGS,
            )
        )

        remove_button_surf = combine_surfaces(
            [ARROW_LEFT_ICON, remove_button_text_surf],
            retrieve_pos_from="midright",
            assign_pos_to="midleft",
            offset_pos_by=(0, 0),
            padding=2,
            background_color=BUTTON_BG,
        )

        draw_depth_finish(remove_button_surf)

        topright = self.chosen_cases_listbox.rect.move(-5, 10).midbottom

        remove_button = (

            Button(
                remove_button_surf,
                command=self.remove_selected,
                coordinates_name='topright',
                coordinates_value=topright,
            )

        )

        widgets.append(remove_button)

        ## remove all button

        remove_all_button_text_surf = (
            render_text(
                text="Remove all",
                **BUTTON_SETTINGS,
            )
        )

        remove_all_button_surf = combine_surfaces(
            [ARROW_LEFT_DOUBLE_ICON, remove_all_button_text_surf],
            retrieve_pos_from="midright",
            assign_pos_to="midleft",
            offset_pos_by=(0, 0),
            padding=2,
            background_color=BUTTON_BG,
        )

        draw_depth_finish(remove_all_button_surf)

        topleft = self.chosen_cases_listbox.rect.move(5, 10).midbottom

        remove_all_button = (

            Button(
                remove_all_button_surf,
                command=self.remove_all,
                coordinates_name='topleft',
                coordinates_value=topleft,
            )

        )

        widgets.append(remove_all_button)

        ### 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

        ### widgets to select play speed

        ## label

        speed_label = Object2D.from_surface(
            surface=render_text(
                text="Speed (frames/second):", **TEXT_SETTINGS
            ),
            coordinates_name="topleft",
            coordinates_value=topleft,
        )

        widgets.append(speed_label)

        ## entry

        midleft = speed_label.rect.move(10, 0).midright

        self.speed_entry = IntFloatEntry(
            value=0, # max/uncapped
            min_value = 0,
            numeric_classes_hint='int_float',
            loop_holder=self,
            command=self.check_speed_button_surfs,
            width=100,
            coordinates_name="midleft",
            coordinates_value=midleft,
        )

        widgets.append(self.speed_entry)

        ## extra buttons for speed

        midleft = self.speed_entry.rect.move(10, 0).midright

        set_speed = self.speed_entry.set

        for text, speed in (
            ("0.25x", FPS//4),
            ("0.5x", FPS//2),
            ("1x", FPS),
            ("2x", FPS*2),
            ("4x", FPS*4),
            ("max/uncapped", 0),
        ):

            speed_button = Button.from_text(
                text=text,
                command=partial(set_speed, speed),
                coordinates_name="midleft",
                coordinates_value=midleft,
                **BUTTON_SETTINGS,
            )

            highlighted_surf = (
                render_text(
                    text=text,
                    **HIGHLIGHTED_SPEED_BUTTON_SETTINGS,
                )
            )

            SPEED_TO_BUTTON[speed] = speed_button

            SPEED_BUTTON_SURF_MAP[speed_button] = (
                speed_button.image, highlighted_surf
            )

            midleft = speed_button.rect.midright

            draw_depth_finish(speed_button.image)

            widgets.append(speed_button)

        ### update speed button surfs
        self.check_speed_button_surfs()

        ### 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, position and store form related buttons

        ## start button

        self.start_button = Button.from_text(
            text="Start system testing session",
            command=self.trigger_system_testing,
            **BUTTON_SETTINGS,
        )

        draw_depth_finish(self.start_button.image)

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

        ## cancel button

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

        draw_depth_finish(self.cancel_button.image)

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

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