def __init__(
        self,
        value="",
        options=("",),
        loop_holder=None,
        clamp_area=SCREEN_RECT,
        max_width=155,
        font_path=ENC_SANS_BOLD_FONT_PATH,
        font_height=ENC_SANS_BOLD_FONT_HEIGHT,
        antialiased=True,
        foreground_color=OPTION_MENU_FG,
        background_color=OPTION_MENU_BG,
        hovered_foreground_color=OPTION_MENU_HOVERED_FG,
        hovered_background_color=OPTION_MENU_HOVERED_BG,
        unhovered_foreground_color=(OPTION_MENU_UNHOVERED_FG),
        unhovered_background_color=(OPTION_MENU_UNHOVERED_BG),
        draw_on_window_resize=empty_function,
        name="option_menu",
        coordinates_name="topleft",
        coordinates_value=(0, 0),
        command=empty_function,
    ):
        """Store data and perform setups.

        Parameters
        ==========

        value (any python literal)
            value assumed by the widget. Must be present
            in the 'options' argument.
        options (iterable of values)
            values the widget is allowed to assume. Each
            value in the options must be a python literal.
        loop_holder
        (obj with handle_input-update-draw operations)
            The loop holder regarded as the parent of
            the object.
        clamp_area (pygame.Rect instance)
            area to which the options will be clamped when
            they are expanded.
        width (integer)
            widget width in pixels.
        font_path (string)
            a key used to define which font file to used;
            for available keys, check the FONT_PATH_MAP
            dictionary in textman/font.py.
        font_height (integer)
            font height in pixels.
        antialiased (boolean)
            indicates whether the text should be antialiased
            or not.
        foreground_color (sequence of integers)
            the integers represent the values of red, blue
            and green channels respectively, with values
            from 0 to 255, all inclusive; the color is
            used for the text.
        background_color (sequence of integers)
            same as foreground color, but used for the
            background.
        hovered_foreground_color (sequence of integers)
            same as foreground color, but used for the
            foreground of hovered surfaces.
        hovered_background_color (sequence of integers)
            same as foreground color, but used for the
            background of hovered surfaces.
        unhovered_foreground_color (sequence of integers)
            same as foreground color, but used for the
            foreground of unhovered surfaces.
        unhovered_background_color (sequence of integers)
            same as foreground color, but used for the
            background of unhovered surfaces.
        name (string)
            an optional arbitrary string which is stored
            in the 'name' attribute of the instance;
            may be used to help identify the widget.
        coordinates_name (string)
            attribute name of pygame.Rect wherein to set the
            position information from the coordinates value
            parameter.
        coordinates_value (2-tuple of integers)
            represents a position in 2d space; the values of
            x and y axes, respectively.
        command (callable)
            callable executed whenever an option is selected.
        """
        ### make sure options is a list
        options = list(options)

        ### validate value and options
        self.validate_value_and_options(value, options)

        ### store value and options

        self.value = value
        self.options = options
        self.clamp_area = clamp_area

        ### store other attributes

        self.command = command
        self.loop_holder = loop_holder
        self.name = name

        self.draw_on_window_resize = draw_on_window_resize

        ### define a max width taking the given width and
        ### arrow's width into account

        ## obtain the arrow's width

        arrow_width = get_arrow_surf(foreground_color, font_height).get_width()

        ## calculate the max text width

        max_text_width = max_width if not max_width else max_width - arrow_width

        ### gather text style data for each kind of text
        ### surfaces to be created;
        ###
        ### note that the "chosen text settings",
        ### different than the "hovered text settings",
        ### has the max width specified; this will cause
        ### both text settings to never override each
        ### other within the second nesting level of the
        ### OPTIONS_TO_STYLE_DATA dictionary;
        ###
        ### this is important, because even in cases where
        ### the "hovered" settings and the "chosen"
        ### settings are practically equal (when the max
        ### width is 0), they are subject to different
        ### treatments;
        ###
        ### for instance, chosen surfaces have an arrow
        ### blitted at their right end and have a border
        ### drawn around them;
        ###
        ### in other words, there must always be something
        ### to differentiate them, and the max width
        ### value is does the trick;

        self.chosen_text_settings = {
            "font_path": font_path,
            "font_height": font_height,
            "antialiased": antialiased,
            "max_width": max_text_width,
            "foreground_color": foreground_color,
            "background_color": background_color,
        }

        self.hovered_text_settings = {
            "font_path": font_path,
            "font_height": font_height,
            "antialiased": antialiased,
            "foreground_color": hovered_foreground_color,
            "background_color": hovered_background_color,
        }

        self.unhovered_text_settings = {
            "font_path": font_path,
            "font_height": font_height,
            "antialiased": antialiased,
            "foreground_color": unhovered_foreground_color,
            "background_color": unhovered_background_color,
        }

        ### build widgets that form the OptionMenu instance
        self.build_widget_structure()

        ### position rect

        setattr(self.rect, coordinates_name, coordinates_value)

        ### define behaviours for used protocols

        ## loop holder update operation
        self.update = empty_function

        ## method for mouse interaction protocol
        self.on_mouse_release = self.get_focus

        ## drawing behaviour
        self.draw = self.draw_collapsed

        ## input handling
        self.handle_input = self.handle_events_and_mouse_pos
Store data and perform setups.

        Parameters
        ==========

        value (any python literal)
            value assumed by the widget. Must be present
            in the 'options' argument.
        options (iterable of values)
            values the widget is allowed to assume. Each
            value in the options must be a python literal.
        loop_holder
        (obj with handle_input-update-draw operations)
            The loop holder regarded as the parent of
            the object.
        clamp_area (pygame.Rect instance)
            area to which the options will be clamped when
            they are expanded.
        width (integer)
            widget width in pixels.
        font_path (string)
            a key used to define which font file to used;
            for available keys, check the FONT_PATH_MAP
            dictionary in textman/font.py.
        font_height (integer)
            font height in pixels.
        antialiased (boolean)
            indicates whether the text should be antialiased
            or not.
        foreground_color (sequence of integers)
            the integers represent the values of red, blue
            and green channels respectively, with values
            from 0 to 255, all inclusive; the color is
            used for the text.
        background_color (sequence of integers)
            same as foreground color, but used for the
            background.
        hovered_foreground_color (sequence of integers)
            same as foreground color, but used for the
            foreground of hovered surfaces.
        hovered_background_color (sequence of integers)
            same as foreground color, but used for the
            background of hovered surfaces.
        unhovered_foreground_color (sequence of integers)
            same as foreground color, but used for the
            foreground of unhovered surfaces.
        unhovered_background_color (sequence of integers)
            same as foreground color, but used for the
            background of unhovered surfaces.
        name (string)
            an optional arbitrary string which is stored
            in the 'name' attribute of the instance;
            may be used to help identify the widget.
        coordinates_name (string)
            attribute name of pygame.Rect wherein to set the
            position information from the coordinates value
            parameter.
        coordinates_value (2-tuple of integers)
            represents a position in 2d space; the values of
            x and y axes, respectively.
        command (callable)
            callable executed whenever an option is selected.
        
nodezator/widget/optionmenu/main.py