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

        ### instantiate a caption for the form

        caption_label = Object2D.from_surface(
            surface=(
                render_text(
                    text=(t.user_preferences_form.caption),
                    border_thickness=2,
                    border_color=(TEXT_SETTINGS["foreground_color"]),
                    **TEXT_SETTINGS,
                )
            ),
        )

        widgets.append(caption_label)

        labels = List2D()

        ### create specific widgets to edit user preferences

        for label_text in (
            t.user_preferences_form.language,
            t.user_preferences_form.backup_files,
            t.user_preferences_form.user_logger_lines,
            t.user_preferences_form.custom_stdout_lines,
            "Text editor behavior",
        ):

            label_obj = Object2D.from_surface(
                render_text(text=f"{label_text}:", **TEXT_SETTINGS)
            )

            labels.append(label_obj)

        lang_option_menu = OptionMenu(
            loop_holder=self,
            options=AVAILABLE_LANGUAGES,
            value=USER_PREFS["LANGUAGE"],
            draw_on_window_resize=self.draw,
            name="LANGUAGE",
            max_width=0,
        )

        number_backups_intfloat_entry = IntFloatEntry(
            loop_holder=self,
            value=USER_PREFS["NUMBER_OF_BACKUPS"],
            name="NUMBER_OF_BACKUPS",
            width=65,
            min_value=0,
            numeric_classes_hint="int",
            allow_none=False,
            draw_on_window_resize=self.draw,
        )

        user_logger_lines_intfloat_entry = IntFloatEntry(
            loop_holder=self,
            value=USER_PREFS["USER_LOGGER_MAX_LINES"],
            name="USER_LOGGER_MAX_LINES",
            min_value=0,
            width=90,
            numeric_classes_hint="int",
            allow_none=False,
            draw_on_window_resize=self.draw,
        )

        custom_stdout_lines_intfloat_entry = IntFloatEntry(
            loop_holder=self,
            value=USER_PREFS["CUSTOM_STDOUT_MAX_LINES"],
            name="CUSTOM_STDOUT_MAX_LINES",
            min_value=0,
            width=90,
            numeric_classes_hint="int",
            allow_none=False,
            draw_on_window_resize=self.draw,
        )

        text_editor_behavior_option_menu = OptionMenu(
            loop_holder=self,
            options=("default", "vim-like"),
            value=USER_PREFS["TEXT_EDITOR_BEHAVIOR"],
            name="TEXT_EDITOR_BEHAVIOR",
            draw_on_window_resize=self.draw,
            max_width=0,
        )

        labels.rect.snap_rects_ip(
            retrieve_pos_from="bottomleft",
            assign_pos_to="topleft",
            offset_pos_by=(0, 5),
        )

        labels.rect.topleft = widgets.rect.move(0, 5).bottomleft

        widgets.extend(labels)

        self.prefs_widgets = prefs_widgets = List2D(
            [
                lang_option_menu,
                number_backups_intfloat_entry,
                user_logger_lines_intfloat_entry,
                custom_stdout_lines_intfloat_entry,
                text_editor_behavior_option_menu,
            ]
        )

        right = max(label.rect.right for label in labels) + 5

        for (pref_widget, label) in zip(prefs_widgets, labels):

            pref_widget.rect.midleft = (right, label.rect.centery)

        widgets.extend(prefs_widgets)

        ### create, position and store form related buttons

        ### create form buttons

        ## submit button

        self.finish_button = Button.from_text(
            text=(t.user_preferences_form.finish),
            command=CallList(
                [
                    self.finish_form,
                    self.exit_loop,
                ]
            ),
            **BUTTON_SETTINGS,
        )

        draw_depth_finish(self.finish_button.image)

        self.finish_button.rect.topright = widgets.rect.move(0, 5).bottomright

        ## cancel button

        self.cancel_button = Button.from_text(
            text=(t.user_preferences_form.cancel),
            command=self.exit_loop,
            **BUTTON_SETTINGS,
        )

        draw_depth_finish(self.cancel_button.image)

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

        ## store

        self.finish_button.rect.topright = widgets.rect.move(0, 5).bottomright

        self.cancel_button.rect.topright = self.finish_button.rect.move(-5, 0).topleft

        widgets.extend((self.cancel_button, self.finish_button))
Build widgets to hold settings for edition.
nodezator/userprefsman/generalform.py