+
    KiU0  c                   s   R t ^ RIt^ RIt^ RIHtHtHtHtHtH	t	H
t
Ht ^ RIt^ RIHtHtHtHtHt ^ RIHt ^ RIHt ^ RIHt ^ RIHtHtHt ^ RIHt ]'       d   ^ R	IH t  ^ R
I!H"t"  ^ RI#H$t$ R+t&R,t']! 4       t(R R lt)R R lt*R R lt+R R lt,R R lt-]	! R]P\                  R7      t/R-R R llt0R t1R R lt2R t3R.R lt4R t5R/R  lt6R/R! lt7R" t8R0R# R$ llt9R% t:R1R& lt;R' t<R2R( lt=R) t>R* t?R#   ]% d    Rt$ Li ; i)3z-Various utilities using the GObject frameworkN)TYPE_CHECKINGIterableListOptionalTypeTypeVarUnioncast)Gdk	GdkPixbufGioGLibGtk)settings)MissingMediaError)NotificationSource)datapathmagicsystem)loggerLutrisApplication)LutrisWindow)Imagec                2    V ^8  d   QhR\         R,          /#    returnr   r   Zformat   "=/usr/lib/python3.14/site-packages/lutris/gui/widgets/utils.py__annotate__r       s     D D"56 D    c                  sR    \        R \        P                  P                  4       4      # r   )r   r
   Applicationget_default r!   r   get_applicationr%      s    #S__%@%@%BCCr!   c                    V ^8  d   QhRR/# r   r$   r   r   r   r    r    "   s      "5 r!   c                  s|    \        R \        P                  P                  4       4      p V '       g   \	        R4      hV # )r   z%The LutrisApplication does not exist.)r   r
   r"   r#   RuntimeErrorapplication    r   get_required_applicationr+   "   s1    *COO,G,G,IJKBCCr!   c                r   r   r   r   r   r   r   r   r    r    )   s     7 7.1 7r!   c                 sB    \        4       p V '       d   V P                  # R# )zeReturn the application's main window, or None if it doesn't exist
(though it almost alway does exist)N)r%   windowr(   r*   r   get_main_windowr.   )   s     "#K!,;6$6r!   c                r&   r,   r$   r   r   r   r    r    0   s      . r!   c                 sX    \        4       p V P                  pV'       g   \        R4      hV# )zPReturn the application's main window or raises an exception if
it doesn't exist.zThe main window does not exist.)r+   r-   r'   )r)   r-        r   get_required_main_windowr0   0   s+     +,KF<==Mr!   c                s    V ^8  d   QhR\         \        P                  ,          R\         \        P                  ,          /# )r   widgetr   )r   r   WidgetWindowr   r   r   r    r    :   s,      hszz2 x

7K r!   c                s    V '       dC   \        \        \        P                  ,          V P	                  \        P                  4      4      # R# )zReturns the window that contains a widget, if any. This wll return None
for a widget that is not in a window, rather than returning the widget itself
like get_toplevel().N)r   r   r   r3   Zget_ancestor)r1      &r   get_widget_windowr5   :   s/     HSZZ(&*=*=cjj*IJJr!   TChildWidget)Zboundc                s    V ^8  d   QhR\         \        P                  ,          R\         \        \        ,          ,          R\
        \        ,          /# )r   r1   
child_typer   )r   r   r2   r   r6   r   r   r   r   r    r    G   s<      SZZ .6tL7I.J	,r!   c                sF   \        V \        P                  4      '       d|   V'       dB   V P                  4        Uu. uF&  p\        W!4      '       g   K  \	        \
        V4      NK(  	  up# \        \	        \        \
        ,          V P                  4       4      4      # . # u upi )zReturns the children of any widget; non-containers have no children
and returns an empty list. This can filter out a specific type of child widget if child_type
is not None, but otherwise it returns all children.)
isinstancer   Z	ContainerZget_childrenr   r6   Zlistr   )r1   r7   Zw   && r   get_widget_childrenr:   G   su     &#--((393F3F3Hf3HaJWXLe)Dq)3HffXl3V5H5H5JKLL		 gs   BBc                s6    \         P                  ! RV .4       R# )z8Opens a local or remote URI with the default applicationzxdg-openN)r   Zspawn)Zurir4   r   open_urir;   V   s    
LL*c"#r!   c                sF    V ^8  d   QhR\         R\        \         ,          /# )r   pathr   )strr   r   r   r   r    r    [   s      3 8C= r!   c                s$   \         P                  P                  V 4      ^,          P                  4       pVR9   d   R# VR8X  d   R#  \        P
                  ! V 4      P                  4       pRT9   d   R# RT9   d   R# R#   \         d     R# i ; i)zReturns the canonical file extension for an image,
either 'jpg' or 'png'; we deduce this from the file extension, or if that fails the
file's 'magic' prefix bytes..jpg.pngNzjpeg image datazpng image data)r>   z.jpeg)osr<   ZsplitextZcasefoldr   Z	from_fileZOSError)r<   extZ	file_types   &  r   get_image_file_extensionrB   [   s     ''

4
 
#
,
,
.C

f}OOD)224	 I%9$  s   $B   BBc                s    V P                  4       w  rV P                  4       V,          pV P                  4       V,          pW43# )zReturns the size of a surface, accounting for the device scale;
the surface's get_width() and get_height() are in physical pixels.)Zget_device_scale	get_width
get_height)surfaceZdevice_scale_xZdevice_scale_ywidthheights   &    r   get_surface_sizerH   r   sC     &-%=%=%?"N.0E!N2F=r!   c                s   \        V 4      pV'       g   R# VP                  4       pVP                  4       pV^ ,          V,          V,          pV^,          V,          V,          pV'       d   \        Wx4      pTp\	        WW,          4      p	\	        Wh,          4      p
\
        P                  ! \
        P                  P                  W4      p\
        P                  ! V4      pVP                  Wx4       \        P                  ! W^ ^ 4       VP                  4       P                  \
        P                  P                   4       VP#                  4        VP%                  W"4       V# )a	  Returns a Cairo surface containing the image at the path given. It has the size indicated.

You specify the device_scale, and the bitmap is generated at an enlarged size accordingly,
but with the device scale of the surface also set; in this way a high-DPI image can be
rendered conveniently.

If you pass True for preserve_aspect_ratio, the aspect ratio of the image is preserved,
but will be no larger than the size (times the device_scale).

If there's no file at the path, or it is empty, this function returns None.
N)get_pixbuf_by_pathrC   rD   ZminZroundcairoZImageSurfaceZFormatZARGB32ZContextZscaler   Zcairo_set_source_pixbufZ
get_sourceZ
set_extendZExtendZPADZpaintZset_device_scale)r<   sizeZdevice_scalepreserve_aspect_ratiopixbufZpixbuf_widthZpixbuf_heightZscale_xZscale_yZpixel_widthZpixel_heightrE   Zcrs   &&&&         r   get_scaled_surface_by_pathrN   {   s     %F##%L%%'MAw%5GAw&,6Gg'./K01L  !4!4kPG	w	BHHWAq1MMOu||//0HHJ\8Nr!   c                s    V '       d   V ^ ,          V ^,          8X  d   RpMRp\         P                  P                  \        P                  ! 4       V4      # )z~Returns the path to the default icon for the size given; it's
a Lutris icon for a square size, and a gradient for other sizes.zmedia/default_icon.pngzmedia/default_banner.png)r@   r<   joinr   get)rK   filename   & r   get_default_icon_pathrS      s;     47d1g%+-77<<11r!   c                s,   \         P                  ! V RR7      '       g   R# V'       dO   Vw  r4V'       d!   \        P                  P	                  WV4      # \        P                  P                  WVRR7      # \        P                  P                  V 4      # )a&  Reads an image file and returns the pixbuf. If you provide a size, this scales
the file to fit that size, preserving the aspect ratio if preserve_aspect_ratio is
True. If the file is missing or empty, or if 'path' is None or empty,
this returns None. Still raises GLib.GError for corrupt files.T)Zexclude_emptyNF)rL   )r   Zpath_existsr	   PixbufZnew_from_file_at_sizeZnew_from_file_at_scaleZnew_from_file)r<   rK   rL   rF   rG      &&&  r   rI   rI      sv    
 d$77 ##99$vNN66tFbg6hh))$//r!   c                s     \        WV4      pV'       g   \        V R7      hV#   \        P                   d4   p\        P
                  ! RT 4       \        \        T4      T R7      ThRp?ii ; i)a  Reads an image file and returns the pixbuf. If you provide a size, this scales
the file to fit that size, preserving the aspect ratio if preserve_aspect_ratio is
True. If the file is missing or unreadable, or if 'path' is None or empty, this raises
MissingMediaError.)rQ   z!Unable to load icon from image %s)ZmessagerQ   N)rI   r   r   ZGErrorr   Z	exceptionr=   )r<   rK   rL   rM   ZexrU   r   get_required_pixbuf_by_pathrV      sb    
H#D0EF#T22;; H<dCB$?RGHs   !$ A,.A''A,c                st    V '       g   R# \         P                  P                  4       pVP                  V 4      # )zFThis tests if a GTK stock icon is known; if not we can try a fallback.F)r   	IconThemer#   Zhas_icon)nameZthemerR   r   has_stock_iconrY      s)    MM%%'E>>$r!   c                st    V ^8  d   QhR\         \        \        \        ,          3,          R\        R\        /# )r   namesfallback_namer   )r   r=   r   r   r   r   r    r       s0     
 
5hsm!34 
S 
lo 
r!   c                st    \        V \        4      '       d   V .p V  F  p\        V4      '       g   K  Vu # 	  V# )zUsed to select a stock icon that actually exists in the icon set; it tries all the names given,
and returns the first where has_stock_icon is true. If none pass the test, returns fallback_name instead.)r8   r=   rY   )rZ   r[   rX   r9   r   pick_stock_iconr\      s:     %$K  r!   c                s:   V P                  4       P                  RR4      p. ROpRR.pV Fl  pV Fc  p\        P                  P	                  \
        P                  WAV,           4      p\        P                  P                  V4      '       g   K_  Vu u # 	  Kn  	  R# )a^  Finds the icon file for an icon whose name is given; this searches the icons
in Lutris's runtime directory. The name is normalized by removing spaces
and lower-casing it, and both .png and .svg files with the name can be found.

Arguments:
icon_name -- The name of the icon to retrieve

Returns:
    The path to the icon, or None if it wasn't found.
Z Z r?   z.svgN)zicons/hicolor/64x64/appszicons/hicolor/24x24/appsiconszicons/hicolor/scalable/appszicons/hicolor/symbolic/apps)ZlowerZreplacer@   r<   rO   r   RUNTIME_DIRZexists)Z	icon_namerQ   Zsearch_directoriesZ
extensionsZ
search_dirrA   Z	icon_paths   &      r   get_runtime_icon_pathr_      s      ((b1H &!J(
CX%9%9:RU~VIww~~i((    )
 r!   c                s   \         P                  ! V 4      pVP                  R4      pVw  r4\        VR,          4      pVP                  w  rg\        WeV,          ,          4      p\        W,
          ^,          4      p	VP                  W3\         P                  P                  R7      pVP                  V	^ W9,           V34      p\         P                  ! RW43R4      p
V
P                  V^ ^ W534       \         P                  ! RW43R4      p\         P                  ! \        P                  P                  \        P                  ! 4       R4      4      pVP                  WR7       V# )z&Converts an image to a pane backgroundZRGBAg?Zresamplezmedia/mask.pngmask)    rc   rc   rc   )r   ZopenZconvertintrK   resize
ResamplingBICUBICcropZnewpaster@   r<   rO   r   rP   )Zbackground_pathtarget_sizeZcoverarttarget_widthtarget_heightZimage_heightZ
orig_widthZorig_heightrF   ZoffsetZcoverart_bgZ
backgroundrb   s   &&           r   convert_to_backgroundrm     s$   zz/*H'H"-L}t+,L&mmJ 
[89:E%&!+,F4u?O?O?W?WXH}}fa)>MNH ))F\$A<PKhA| BC 6L#@,OJ::bggll8<<>3CDED[,r!   c                 s   V P                   w  r#W#,          pVw  rVWV,          pWG8  d   \        W&V,          ,          4      pTp	MTp\        W5V,          ,          4      p	\        W,
          ^,          4      p
\        W,
          ^,          4      pV P                  W3\        P                  P
                  R7      p V P                  WW,
          W,
          34      p V # )r   r`   )rK   rd   re   r   rf   rg   rh   )
base_imagerj   
base_widthbase_heightZ
base_ratiork   rl   Ztarget_ratiorF   rG   Zx_offsetZy_offsets   &&          r   thumbnail_imagerq   !  s    (ooJ)J"-L/L !J+"=>?[:$=>?E(A-.HF*a/0H""E?U=M=M=U=U"VJ(e6FHY!Z[Jr!   c                 s    V P                   w  r4VP                   w  rV\        W5,
          ^,          4      p\        WF,
          ^,          4      pV P                  WWV,           Wh,           3VR7       V # )r   ra   )rK   rd   ri   )	rn   Zoverlay_imageZpositionro   rp   Zoverlay_widthZoverlay_heightZoffset_xZoffset_ys	   &&&      r   paste_overlayrr   5  sp    (ooJ$1$6$6!MJ.!34HK0A56H(H,DnF_`gt   r!   c           
     s    \         P                   ! RV P                  4       4      pV P                  w  r#\        P                  P                  V\        P                  P                  R^W#V^,          4      # )z$Converts a PIL Image to a GDK PixbufZBT)arrayZtobytesrK   r	   rT   Znew_from_dataZ
ColorspaceZRGB)ZimageZimage_arrayrF   rG   s   &   r   image2pixbufrt   @  sZ    ++c5==?3KJJME))+y7K7K7O7OQUWXZ_inqrirssr!   c                 s    \         P                  P                  4       p \        P                  P                  \        P                  R4      pWP                  4       9  d   V P                  V4       R# R# )z/Add the lutris icon folder to the default themer]   N)
r   rW   r#   r@   r<   rO   r   r^   Zget_search_pathZprepend_search_path)Z
icon_themeZlocal_theme_pathr/   r   load_icon_themeru   G  sR    **,Jww||H$8$8'B99;;&&'78 <r!   )    rv   )i   iE   )N)T)NT)zpackage-x-generic-symbolic))i@  i8  )gffffff?)@Z__doc__rs   r@   Ztypingr    r   r   r   r   r   r   r   rJ   Zgi.repositoryr   r	   r
   r   r   Zlutrisr   Zlutris.exceptionsr   Zlutris.gui.widgetsr   Zlutris.utilr   r   r   Zlutris.util.logr   Zlutris.gui.applicationr   Zlutris.gui.lutriswindowr   ZPILr   ZImportErrorZ	ICON_SIZEZBANNER_SIZEZMEDIA_CACHE_INVALIDATEDr%   r+   r.   r0   r5   r2   r6   r:   r;   rB   rH   rN   rS   rI   rV   rY   r\   r_   rm   rq   rr   rt   ru   r$   r!   r   <module>rw      s    3  	 V V V  8 8  / 1 / / "84 	,. D7 ~SZZ8$
.$N20&H 
<>(t9c	  Es   (C4 4	D ?D 