def update_image(self):
        """Create and store surface representing value.

        The surface is stored in the 'image' attribute
        of this widget, hence the name of the method.
        """
        ### get value as a tuple of rgba colors

        colors = custom_format_color(self.value, "rgb_tuple", False)

        ### generate surfaces representing color value

        color_surfs = get_color_surfaces(
            colors,
            self.no_of_slots,
        )

        ### define the width of the image surface

        width = (
            ## the width of the icon
            ICON_SIZE[0]
            ## plus the sum of the width of all color
            ## surfaces (we subtract to cause the color
            ## surfaces are blit 2 pixels closer to
            ## each other, thus occupying less space)
            + ((SINGLE_COLOR_SIZE[0] - 2) * len(color_surfs))
            ## plus 8 additional pixels which will use as
            ## additional space before the icon, between the
            ## icon and the color surfaces and after the
            ## color surfaces, so things look better
            + 8
        )

        ### create an image using the calculated width

        image = self.image = render_rect(width, BUTTON_HEIGHT, COLORBUTTON_BG)

        ### if a rect exists, update its width

        try:
            rect = self.rect
        except AttributeError:
            pass
        else:
            rect.width = image.get_width()

        ### blit icon aligned to the midleft of the surface,
        ### 2 pixels to the right, so there's some padding
        ### to its left

        blit_aligned(ICON_SURF, image, "midleft", "midleft", offset_pos_by=(2, 0))

        ### store the distance from the beginning of the
        ### image until the right of the icon (the width
        ### of the icon plus the 2 pixels we used to offset
        ### it; we won't use it here anymore, but in the
        ### 'on_mouse_release' method, to check whether the
        ### mouse hovered the icon;
        self.distance_till_icon_end = ICON_SIZE[0] + 2

        ### blit each color surface in the "image" surface

        ## use the width of the icon as the "start", a fixed
        ## amount to offset the beginning position x where
        ## the color surfaces will be blitted, plus 4
        ## additional pixels (2 pixels of compensation for
        ## the offset we used in the previous step and 2
        ## additional pixels to put space between the
        ## icon and the color surfaces)
        start = ICON_SIZE[0] + 4

        ## use the width of a color surface as the "step"
        ## amount, an amount used to increment at each
        ## iteration, that is, while bliting each color
        ## surface in the image (the step has 2 pixels
        ## subtracted because the color surfaces are
        ## blit closer to each other to take advantage
        ## of their "inclined" shape)
        step = SINGLE_COLOR_SIZE[0] - 2

        ## iterate over each color surface, calculating
        ## an horizontal offset (x offset) relative to the
        ## midleft corner of the "image" surface and using
        ## such offset to blit the color surface in the
        ## suitable position

        for index, surf in enumerate(color_surfs):

            x_offset = start + (index * step)

            blit_aligned(surf, image, "midleft", "midleft", offset_pos_by=(x_offset, 0))
Create and store surface representing value.

        The surface is stored in the 'image' attribute
        of this widget, hence the name of the method.
        
nodezator/widget/colorbutton.py