Repository: gradio-app/gradio
File: gradio/components/image_editor.py (Python)

Code before:
        if self.layers is None or len(self.layers) == 0:
            self.layers = ["Layer 1"]


@document()
@dataclasses.dataclass
class WebcamOptions:
    """
    A dataclass for specifying options for the webcam tool in the ImageEditor component. An instance of this class can be passed to the `webcam_options` parameter of `gr.ImageEditor`.
    Parameters:
        mirror: If True, the webcam will be mirrored.
        constraints: A dictionary of constraints for the webcam.
    """

    mirror: bool = True
    constraints: dict[str, Any] | None = None

@document()
@dataclasses.dataclass
class WatermarkOptions:
    """
    A dataclass for specifying options for the watermark tool in the ImageEditor component.
    
    Parameters:
        watermark: str, Path, PIL.Image.Image, np.ndarray to use as the watermark
        position: (x,y) coordinates for watermark placement
    """
    watermark: Union[str, Path, PIL.Image.Image, np.ndarray, None] = None
    position: tuple[int, int] = (0, 0)

    def __post_init__(self):
        # Validate watermark input
        if self.watermark is not None:
            if not isinstance(self.watermark, (str, Path, PIL.Image.Image, np.ndarray)):
                raise ValueError("Watermark must be a string path, Path, PIL Image, numpy array, or None")
        
        # Validate position tuple
        if not isinstance(self.position, tuple) or len(self.position) != 2:
            raise ValueError("Position must be a tuple of (x,y) coordinates")


@document()
class ImageEditor(Component):
    """
    Creates an image component that, as an input, can be used to upload and edit images using simple editing tools such
    as brushes, strokes, cropping, and layers. Or, as an output, this component can be used to display images.

    Demos: image_editor
    """

    EVENTS = [

Review comment (suggestion):
Hi @PRIME-SV . Looks good. Thanks for addressing changes. I think `position` should also accept strings for common positions like `top-left`, `top-right`, `bottom-left`, `bottom-right`. 

Code after:
        if self.layers is None or len(self.layers) == 0:
            self.layers = ["Layer 1"]


@document()
@dataclasses.dataclass
class WebcamOptions:
    """
    A dataclass for specifying options for the webcam tool in the ImageEditor component. An instance of this class can be passed to the `webcam_options` parameter of `gr.ImageEditor`.
    Parameters:
        mirror: If True, the webcam will be mirrored.
        constraints: A dictionary of constraints for the webcam.
    """

    mirror: bool = True
    constraints: dict[str, Any] | None = None


@document()
@dataclasses.dataclass
class WatermarkOptions:
    """
    A dataclass for specifying options for the watermark tool in the ImageEditor component.

    Parameters:
        watermark: str, Path, PIL.Image.Image, np.ndarray to use as the watermark
        position: (x,y) coordinates as tuple[int, int] or string position ('top-left', 'top-right', 'bottom-left', 'bottom-right'). Default is 'bottom-right'.
    """

    watermark: Union[str, Path, PIL.Image.Image, np.ndarray, None] = None
    position: Union[
        tuple[int, int],
        Literal[
            "top-left",
            "top-right",
            "bottom-left",
            "bottom-right",
        ],
    ] = "bottom-right"

    def __post_init__(self):
        # Validate watermark input
        if self.watermark is not None and not isinstance(
            self.watermark, (str, Path, PIL.Image.Image, np.ndarray)
        ):
            raise ValueError(
                "Watermark must be a string path, Path, PIL Image, numpy array, or None"
            )

        if isinstance(self.position, str):
            valid_positions = {