+
    Ki{  c                   s   R t ^ RIt^ RIHtHt ^ RIHt ^ RIHtH	t	 ^ RI
HtHtHtHtHtHt ^ RIHtHt ^ RIHt ^ RIHt ^ R	IHtHtHt ^ R
IHt ^ RIHt ^ RI H!t! ]'       d   ^ RI"H#t#  ! R R]4      t$ ! R R]PJ                  4      t& ! R R]PN                  4      t( ! R R](4      t) ! R R])4      t* ! R R])4      t+R# )z+Widget generators and their signal handlersN)ABCabstractmethod)gettext)	Parameter	signature)TYPE_CHECKINGAnyCallableDictListOptional)GdkGtk)LutrisConfig)NotificationSource)EditableGridFileChooserEntryLabel)SearchableEntrybox)logger)gtk_safe)	ConfigBoxc                   s  a  ] tR t^t o Rt]]]]3,          ]].]	]
P                  ,          3,          tV 3R lR ltV 3R lR lt]V 3R lR l4       t]P"                  V 3R lR	 l4       tR=V 3R lR lltR=V 3R lR lltR=V 3R lR lltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltR>V 3R lR lltV 3R lR ltV 3R lR  ltR! tR" tR# tR$ t R?R% lt!R& t"R' t#R?R( lt$R) t%R* t&R+ t'R, t(])R- 4       t*]+V 3R. lR/ l4       t,V 3R0 lR1 lt-V 3R2 lR3 lt.V 3R4 lR5 lt/V 3R6 lR7 lt0V 3R8 lR9 lt1V 3R: lR; lt2R<t3V t4R
# )@WidgetGeneratora
  This class generates widgets for an options page. It even adds the widgets
to a 'wrapper' you can supply and, if required, that wrapper goes into a container
which also contains message boxes for errors and warnings.

The specific inner widgets are generated according to an option dict.

The generator also accumulates and tracks the wrappers and containers for future use,
and can update their state via a call to update_widgets(). When doing this, various callables
in the option dicts can be re-evaluated; you provide a set of 'callback_args' and 'callback_kwargs'
that are passed along to these callbacks. These collbacks also take the identifier of the
option, from the 'option' key of the option dict.

'changed' is a NotificationSource for whenever the generated widget changes a value;
the same 'changed' NotificationSource is shared by all the widgets this generator generates.

You can only create new containers, not discard old ones, but you *can* regenerate the widget
inside the wrapper as a way to force it to update.
c                s"   < V ^8  d   QhRRRR/# )   parentr   returnN format__classdict__   "G/usr/lib/python3.14/site-packages/lutris/gui/config/widget_generator.py__annotate__WidgetGenerator.__annotate__,   s     &
 &
{ &
RV &
    c                sz   Wn         W n        W0n        \        4       V n        V P                  P                  V P                  R R7       RV n        RV n        RV n	        RV n
        RV n        RV n        / V n        RV n        RV n        . V n        / V n        . V n        / V n        RV P(                  RV P*                  RV P,                  RV P.                  RV P0                  RV P2                  R	V P4                  R
V P6                  RV P8                  RV P:                  RV P<                  RV P>                  /V n         R# )i  )ZpriorityNlabelZstringboolZrangechoiceZchoice_with_entryZchoice_with_searchZfileZmultiple_fileZ	directoryZmappingZcommand_line)!r   callback_argscallback_kwargsr   changedZregister
on_changed_default_directory_current_parent_current_sectionwrapperdefault_valuetooltip_defaultoptionsoption_widgetoption_containerwarning_messageswrapperssection_framesoption_containers_generate_label_generate_string_generate_bool_generate_range_generate_choice_generate_choice_with_entry_generate_choice_with_search_generate_file_generate_multiple_file_generate_directory_generate_mapping_generate_command_line_generators)selfr   r&   r'   s   &&*,r   __init__ZWidgetGenerator.__init__,   s2   *.)+doo=1526/3 +/!.224376:24 3524;= T))d++D''T))d++!A!A $"C"CD''T9911t--D77J
r"   c                s*   < V ^8  d   QhRS[ RS[RR/# )r   
option_key	new_valuer   Nstrr   r   r   r   r    r!   T   s"      S S T r"   c                s&    V P                  4        R# )zCalled when any value is changed; this is called later than ordinary
handlers for the 'changed' notification, and by default just updates the
widgets.N)update_widgets)rD   rF   rG      &&&r   r)   ZWidgetGenerator.on_changedT   s     	r"   c                    < V ^8  d   QhRS[ /# r   r   rI   r   r   r   r    r!   [   s     ' '3 'r"   c                s    V P                   '       gR   \        4       pVP                  P                  R4      ;'       g     \        P
                  P                  R4      V n         V P                   # )zIThis is the directory selected by default by file and directory choosers.Z	game_pathZ~)r*   r   system_configgetospath
expanduser)rD   lutris_config   & r   default_directory!WidgetGenerator.default_directoryZ   sW     &&&(NM&3&A&A&E&Ek&R&m&mVXV]V]VhVhilVmD#&&&r"   c                s$   < V ^8  d   QhRS[ RR/# )r   new_dirr   NrN   r   r   r   r    r!   c   s     * * * *r"   c                s    Wn         R # N)r*   )rD   rX      &&r   rV   rW   b   s    ")r"   Nc                   < V ^8  d   QhRS[ S[S[3,          RS[S[P
                  ,          RS[S[P                  ,          /# r   optionr-   r   r   rI   r   r
   r   BoxWidgetr   r   r   r    r!   h   s@        DcN  Xcgg=N  ZbcfcmcmZn  r"   c                sV   V P                  W4      pV'       Ed   V P                  '       d   V P                  '       g   V P                  V n        VP                  R4      V P                  8w  d   VP                  R4      V n        V P                  '       dc   \        V P                  RR7      pV P                  P                  V4       VP                  V n        V P                  P                  VRR^ 4       MV P                  V n        V P                  P                  VRR^ 4       V# )zGenerates the option's widget, wrapper and container, and adds the container to the parent;
if the option uses 'section', then the container is actually placed inside a SectionFrame,
or in the previous frame if it is for the same section.sectionTvisibleF)
generate_containerr   r+   rP   r,   SectionFramer5   appendvbox
pack_start)rD   r]   r-   r2   frame   &&&  r   add_containerZWidgetGenerator.add_containerh   s      226C''''+{{$zz)$(=(==(.

9(=%(((()>)>ME''..u5+0::D(KK**5%B+/;;D(  ++,<eUANr"   c                r[   r\   r^   r   r   r   r    r!      s@      c3h (377BS _ghkhrhr_s r"   c                s   V P                  W4      pV'       d   V P                  '       d   VR,          pV P                  WP                  4      pWPP                  V&   VP	                  4        WEn        VR,          Vn        VP                  R4      ;'       g    RVn        \        VP                  R4      4      Vn
        Wn        WPn        V# R# )zpCreates the widget, wrapper, and container; this returns the container
(or the wrapper if there's no container).r]   r#   help ZadvancedN)generate_widgetr-   create_option_containerr6   show_allZlutris_option_keyZlutris_option_labelrP   Zlutris_option_helptextr$   Zlutris_advancedlutris_optionr2   )rD   r]   r-   r1   rF   r2   s   &&&   r   rd   Z"WidgetGenerator.generate_container   s     ,,V=T\\\)J#;;FLLQ1A"":.%%'1;.39'?06<jj6H6N6NB3 04FJJz4J/K,-3*$4!##r"   c                r[   r\   r^   r   r   r   r    r!      s@     0 0d38n 0x?P 0\deheoeo\p 0r"   c                s   VR,          pVR,          pV P                  V4      pV P                  W54      pWPn        RV n        RV n        RV n        V P                  P                  4        V P                  P                  VR4       WP                  V&   V'       d1   VP                  4       pV F  pVP                  4        K  	  W n        M+V P                  WV4      V n        V P                  '       g   R# V P                  P!                  V4      p	V	'       d   V	! WV4      p
M\#        RV,          4      hV P                  V P                  V&   Wn        V P                  ;'       g    \%        V\&        4      '       d   TMRV n        V
'       d   V
P)                  4        V P+                  V P                  WV4       V P-                  V4       V
# )ac  This creates a wrapper box and a label and widget within it according to the options dict
given. The option widget itself, is returned, but this method also sets attributes on the
generator. You get 'wrapper', 'default_value', 'tooltip_default' and 'option_widget' which restates
the return value. This returns None if the entire option should be omitted.r]   typeNzUnknown widget type %s)get_defaultget_settingr.   r/   r1   r2   r3   Zclearr4   Zpopr0   get_childrendestroyr-   create_wrapper_boxrC   rP   Z
ValueError
isinstancerI   rp   configure_wrapper_boxconfigure_warning_messages)rD   r]   r-   rF   Zoption_typedefaultvalueZchildrenchildZfuncr1   s   &&&        r   rn   ZWidgetGenerator.generate_widget   s   
 H%
Vn""6*  5$#! $##%*d+ $*Z ++-H! ""L226'JDL<<<##K0 8M5CDD$(LLj!*#33ff:gWZC[C[ae""$""4<<H''/r"   c          
      s`   < V ^8  d   QhRS[ P                  RS[S[S[3,          RS[RS[RR/# )r   r-   r]   r|   r{   r   N)r   r`   r   rI   r   r   r   r   r    r!      sF     M MSZZ Mc3h MX[ Mfi Mnr Mr"   c                s    V P                  W#V4      pV'       d1   RVP                  n        VP                  RV P                  V4       R# R# )zvConfigures the wrapper box after it is created; this sets its tooltip, sensitivity, and
creates warning message boxes.Tzquery-tooltipN)get_tooltipZpropsZhas_tooltipconnecton_query_tooltip)rD   r-   r]   r|   r{   tooltips   &&&&& r   ry   Z%WidgetGenerator.configure_wrapper_box   s@    
 ""6':(,GMM%OOOT-B-BGL r"   c                sB   < V ^8  d   QhRS[ S[S[3,          RS[RS[/# )r   r]   r|   r{   r   rI   r   r   r   r   r    r!      s*      $sCx.  s r"   c                s    VP                  R 4      pV P                  '       d7   V'       d
   VR,           MRpV\        R4      V P                  ,           ,          pV# )rl   z

rm   z<b>Default</b>: )rP   r/   _)rD   r]   r|   r{   r      &&&& r   r~   ZWidgetGenerator.get_tooltip   sJ    **V$*1g&rGq+,t/C/CCCGr"   c                s6   < V ^8  d   QhRS[ S[S[3,          /# )r   r]   r   r   r   r   r    r!      s     N Nc3h Nr"   c                s    R V9   d,   V P                   P                  \        VR ,          4      4       RV9   d.   V P                   P                  \        VR,          4      4       R# R# )errorwarningN)r3   rf   ConfigErrorBoxConfigWarningBoxrD   r]   rZ   r   rz   Z*WidgetGenerator.configure_warning_messages   sS    f!!((w)HI!!(()9&:K)LM r"   c          	      sl   < V ^8  d   QhRS[ S[S[3,          RS[RS[RS[S[P
                  ,          /# )r   r]   r|   r{   r   )r   rI   r   r
   r   r_   r   r   r   r    r!      sD     
j 
jc3h 
j 
jc 
jV^_b_f_fVg 
jr"   c                s    V P                  RV4      pV'       g   R# \        P                  ! \        P                  P                  ^^RR7      # )zThis creates the wrapper, which becomes the 'wrapper' attribute and which build_option_widget()
populates. Returns None if the option is not visible; in that case no widget is generated either.	availableNT)orientationspacingmargin_bottomrc   )_evaluate_flag_optionr   r_   OrientationZ
HORIZONTAL)rD   r]   r|   r{   r   r   r   rw   Z"WidgetGenerator.create_wrapper_box   s=     ..{FC	ww3??#=#=rYZdhiir"   c                sj   < V ^8  d   QhRS[ S[S[3,          RS[P                  RS[P                  /# r\   )r   rI   r   r   	Containerr   r   r   r    r!      s5      d38n s}} Y\YfYf r"   c                s   V P                   '       dn   \        P                  ! \        P                  P                  RR7      pVP                  VRR^ 4       V P                    F  pVP                  VRR^ 4       K  	  V# V# )zThis creates a wrapper box around the widget wrapper, to support additional controls. The
base implementation wraps 'wrapper' in a Box with the error and warning widgets; if
there are none it just returns 'wrapper'.Tr   rc   F)r3   r   r_   r   VERTICALrh   )rD   r]   r-   r2   widgetrj   r   ro   Z'WidgetGenerator.create_option_container   sq    
    "ww3??3K3KUYZ''qA// ++FE5!D 0 $#Nr"   c                s   < V ^8  d   QhRS[ S[S[3,          RS[S[P
                  ,          RS[RS[RS[S[P
                  ,          /# )r   r]   r   no_labelexpandr   )r   rI   r   r
   r   r`   r$   r   r   r   r    r!      sO      38n.6szz.BNRdh	#**	r"   c                s4   V P                   '       d   V'       g:   RV9   d3   VR,          p\        V4      pV P                   P                  VRR^ 4       V'       d=   VP                  RR4      pV'       d   VR8g  pV P                   P                  W$V^ 4       V# )a  This is called by the generator methods to place their widget into the wrapper, usually with
a label taken from 'option'.

The default labeling and placement is suitable for our ConfigBoxes, but we override this to
get a different layout for PreferencesBox.

Some generators do their own labelling, and pass True for no_label; this method will
pack the widget with no label in that case.

This method returns the widget.r#   FZsizeNZsmall)r-   r   rh   rP   )rD   r]   r   r   r   r#   Zoption_sizes   &&&&&  r   build_option_widgetZ#WidgetGenerator.build_option_widget   s|     <<<6 1we''ueQ?$jj6(G3F''Br"   c                s   < V ^8  d   QhRR/# )r   r   Nr   r   r   r   r    r!     s     / / /r"   c                sj   V P                   P                  4        FJ  w  r\        VR4      '       g   K  VP                  pV P                  V,          pV P                  W2V4       KL  	  V P                   F:  pVP                  4       pVP                  V4       VP                  V'       * 4       K<  	  R# )zCall this to update the visibility, sensitivity and other properties of
the widgets, wrappers and containers already generated.rq   N)
r6   itemshasattrrq   r4   update_option_containerr5   has_visible_childrenset_visibleset_no_show_all)rD   rF   	containerr]   r-   ri   rc   s   &      r   rJ   ZWidgetGenerator.update_widgets  s     &*%;%;%A%A%C!Jy/22"00--
3,,VH	 &D ((E002Gg&!!g+. )r"   c                sN   < V ^8  d   QhRS[ P                  RS[ P                  /# )r   r   r-   )r   r   r   r   r   r    r!   *  s&     ) ) )QTQ^Q^ )r"   c                s2   VP                  4        F(  p\        VR4      '       g   K  VP                  W4       K*  	  V P                  V4      pVP	                  V4       VP                  V'       * 4       V P                  V4      pVP                  V4       R# )zThis method updates an option container and its wrapper; this re-evaluates the
relevant options in case they contain callables and those callables return different
results.update_messageN)ru   r   r   get_visibilityr   r   get_conditionZset_sensitive)rD   r]   r   r-   r}   rc   	conditions   &&&&   r   r   Z'WidgetGenerator.update_option_container*  s     ++-Eu.//$$V2 .
 %%f-g&!!g+. ,,V4	i(r"   c                s   VR,          p\        V4      pVP                  R4       VP                  \        P                  P
                  4       VP                  \        P                  P                  4       V P                  WRR7      # )zGenerate a simple label.r#   Tr   )	r   set_use_markup
set_halignr   AlignSTART
set_valignCENTERr   )rD   r]   r|   r{   textr#   s   &&&&  r   r7   ZWidgetGenerator._generate_label@  sf    gdT")))*'''EEr"   c                s   a a VV 3R lpVR,          o\         P                  ! 4       pTP                  T;'       g    T;'       g    R4       VP                  RV4       S P	                  W4      # )zGenerate an entry box.c                s\   < SP                   P                  SV P                  4       4       R# )z,Action triggered for entry 'changed' signal.N)r(   fireget_text)entryrF   rD   s   &r   r)   Z4WidgetGenerator._generate_string.<locals>.on_changedM  s    LLj%..*:;r"   r]   rm   r(   )r   Entryset_textr   r   )rD   r]   r|   r{   r)   r   rF      f&&&  @r   r8   Z WidgetGenerator._generate_stringJ  sZ    	< H%
		u----2.i,''66r"   c                sV  a a VV 3R lpR pVR,          oV! V4      pVf   \        V! V4      4      p\        P                  ! V\        P                  P                  R7      pVP                  RV4       V'       d   \        R4      M
\        R4      S n        S P                  WRR	7      # )
zGenerate a switch.c                s\   < SP                   P                  SV P                  4       4       R# )z'Action for the switch's toggled signal.N)r(   r   
get_active)r   Z_gparamrF   rD      &&r   on_notify_activeZ8WidgetGenerator._generate_bool.<locals>.on_notify_active\  s     LLj&*;*;*=>r"   c                s    V f   R# \        V \        4      '       d3   V P                  4       P                  4       pVR8X  d   R# VR8X  d   R# R# \	        V 4      # )zVConvert values to booleans in a way that won't decide that
the string 'False' is True!NZtrueTZfalseF)rx   rI   ZcasefoldZstripr$   )Z
to_convertr   rU   r   to_boolZ/WidgetGenerator._generate_bool.<locals>.to_bool`  sS     !J,,!**,2246>W_ J''r"   r]   )activeZvalignznotify::activeZEnabledZDisabledF)r   )	r$   r   ZSwitchr   r   r   r   r/   r   )	rD   r]   r|   r{   r   r   r   ZswitchrF   s	   f&&&    @r   r9   ZWidgetGenerator._generate_boolY  s    	?	(  H%
>''*+F6#))2B2BC')9:/6q|AjM''u'EEr"   c                s  a a	 V	V 3R lpVR,          o	VR,          pVR,          p\         P                  ! \        V4      \        V4      \        V4      ^^ ^ 4      p\         P                  ! 4       pVP	                  V4       TP                  T;'       g    T;'       g    ^ 4       VP                  RV4       S P                  W4      # )zGenerate a ranged spin button.c                `   < V P                  4       pSP                  P                  SV4       R# )z1Action triggered on spin button 'changed' signal.N)Zget_value_as_intr(   r   )r   rG   rF   rD      & r   r)   Z3WidgetGenerator._generate_range.<locals>.on_changed  s%    //1ILLj)4r"   r]   ZminZmaxr(   )r   Z
AdjustmentZfloatZ
SpinButtonZset_adjustmentZ	set_valuer   r   )
rD   r]   r|   r{   r)   Zmin_valZmax_valZ
adjustmentZspin_buttonrF   s
   f&&&     @r   r:   ZWidgetGenerator._generate_range}  s    	5
 H%
--^^E'NE'NE'NTUWXZ[\
nn&"":.e33w33!4Iz2''<<r"   c                s  a aaaaaaaa VVV 3R lpVVV3R loR pVV 3R lpSR,          oS P                  RRS4      o\        P                  ! \        \        4      oV! 4        V'       d2   \        P                  P                  S4      pVP                  ^ 4       MY\        P                  P                  S4      p\        P                  ! 4       p	VP                  V	R4       VP                  V	R	^ 4       VP                  ^4       S! 4       w  roSV
 UUu. uF  w  rVNK	  	  upp9   d   VP                  S4       MnV'       dV   VP                  4        F@  p\        V\        P                  4      '       g   K%  TP!                  S;'       g    R
4        M	  MVP                  S4       VP#                  RV4       VP#                  RV4       VP%                  \        P&                  P(                  4       R VV V3R llpV'       g,   SS9  d%   S P*                  P-                  \/        V4      4       S P1                  SV4      # u uppi )z%Generate a combobox (drop-down menu).c                  s   < S! 4       w  rpV  F  pSP                  V4       K  	  V'       d   \        V4      Sn        R # R # rY   )rf   rI   r/   )expandedr/   Z_valid_choicesr%   expand_combobox_choices	liststorerD   s       r   populate_combobox_choicesZCWidgetGenerator._generate_choice.<locals>.populate_combobox_choices  s?    8O8Q5H~"  ( # '*?';$ r"   c                  s  < . p R p. pRpS F  p\        V\        4      '       d   WD3pV^,          S8X  d   RpV^,          S8X  d,   V^ ,          p\        R4      V^ ,          ,          V^,          3pVP                  V^,          4       V P                  V4       K  	  V'       g   S'       d   V P	                  ^ SS34       WV3# )NFTz%s (default))rx   rI   r   rf   insert)r   r/   ZvalidZ	has_valuer%   choicesr{   r|   s        r   r   ZAWidgetGenerator._generate_choice.<locals>.expand_combobox_choices  s    H"OEI!fc**$-F!9% $I!9'&,QiO/&);VAYGFVAY'' " E5>2e33r"   c                s(    V P                  R4       R# )z]Prevents users from accidentally changing configuration values
while scrolling down dialogs.
scroll-eventF)Zstop_emission_by_name)r   Z_eventrZ   r   on_combobox_scrollZ<WidgetGenerator._generate_choice.<locals>.on_combobox_scroll  s     ((8r"   c                s  < V P                  4       pV P                  4       pRpV^ 8  d6   V P                  4       '       d   V P                  4       P	                  4       pMW,          ^,          pSP
                  P                  SV4       R# )z.Action triggered on combobox 'changed' signal.N)Z	get_modelr   Zget_has_entryZ	get_childr   r(   r   )r   Z
list_storer   Zoption_valuerF   rD   s   &   r   on_combobox_changeZ<WidgetGenerator._generate_choice.<locals>.on_combobox_change  ss    ))+J&&(FLz''))#)#3#3#5#>#>#@L)1!4LLj,7r"   r]   r   NTr   rm   r(   r   c                s$    V ^8  d   QhR\         /# )r   keyrN   )r   s   "r   r    Z6WidgetGenerator._generate_choice.<locals>.__annotate__  s     	g 	gc 	gr"   c                 s|   < SP                  V SP                  S4      4      pVS9   d   R # \        R4      V,          # )NzJThe setting '%s' is no longer available. You should select another choice.)rt   rs   r   )r   vr]   rD   valid_choicess   & r   get_invalidity_errorZ>WidgetGenerator._generate_choice.<locals>.get_invalidity_error  s=      d&6&6v&>?AM!abefffr"   )_evaluate_optionr   	ListStorerI   ZComboBoxZnew_with_model_and_entryZset_entry_text_columnZnew_with_modelCellRendererTextrh   Zadd_attributeZset_id_columnZset_active_idru   rx   r   r   r   r   r   r   r3   rf   r   r   )rD   r]   r|   r{   	has_entryr   r   r   ZcomboboxZcellZexpanded_choicesZ_tooltip_defaultZ_kr   Zchr   r   r   r   rF   r   s   ffff&           @@@@@r   r;   Z WidgetGenerator._generate_choice  s   	<	4&	
	8 H%
''	4@MM#s+	!#||<<YGH**1- ||229=H'')Dd+""43q!<S<U9M$45$452Q$455""5)++-b#)),,KK, .
 ""7+$67);<CII,,-	g 	g U-7!!(()9:N)OP''991 6s   Ic                *    V P                  WVR R7      # )T)r   )r;   rD   r]   r|   r{      &&&&r   r<   Z+WidgetGenerator._generate_choice_with_entry  s    $$VGt$LLr"   c                s   a a VV 3R lpVR,          oVR,          p\        YR;'       g    T4      pVP                  RV4       S P                  W4      # )zGenerate a searchable combo boxc                 s@   < SP                   P                  SV4       R # rY   )r(   r   )_widgetrG   rF   rD   r   r   r)   Z@WidgetGenerator._generate_choice_with_search.<locals>.on_changed  s    LLj)4r"   r]   r   r(   )r   r   r   )rD   r]   r|   r{   r)   r   ZentryboxrF      f&&&   @r   r=   Z,WidgetGenerator._generate_choice_with_search  sQ    	5 H%
#%g/?/?@J/''99r"   c           	     sV  a a
 V
V 3R lpVR,          o
\        VP                  R4      4      pV'       g   TpRV9   d.   \        4       pVP                  P                  VR,          4      pMS P                  p\        \        R4      \        P                  P                  VVVVR7      p	V'       d   \        P                  P                  V4      '       go   \        P                  P                  V4      p\        P                  P                  V4      '       g+   \        P                  P                  S P                  V4      pV	P                  P!                  V4       V	P#                  \        P$                  P&                  4       V	P)                  RV4       S P+                  W4      # )z0Generate a file chooser button to select a file.c                r   z2Action triggered when the field's content changes.Nr   r(   r   r   r   rF   rD   r   r   r)   Z2WidgetGenerator._generate_file.<locals>.on_changed  #    >>#DLLj$/r"   r]   warn_if_non_writable_parentdefault_pathzSelect file)titleactionr   r   r   shell_quotingr(   )r$   rP   r   rO   rV   r   r   r   FileChooserActionOPENrQ   rR   ZisabsrS   Zjoinr   r   r   r   r   r   r   )rD   r]   r|   r{   r   r)   r   rT   Zchooser_default_pathZfile_chooserrF   s   f&&&&     @r   r>   ZWidgetGenerator._generate_file  s;   	0
 H%
&*6::6S+T&U#EV#(NM#0#>#>#B#B6.CY#Z #'#9#9 'M"((--(C-'
 77==''**51ww}}U++GGLL)?)?GE''.		 0 01Y
3''==r"   c                r   )T)r   )r>   r   r   r   rB   Z&WidgetGenerator._generate_command_line,  s    ""6'"NNr"   c                sX  a aa VVV 3R lpVVV 3R lpVR,          oVR,          p\         P                  ! \        4      o\         P                  ! \         P                  P
                  R7      p\        VR,           4      pVP                  \         P                  P                  4       \         P                  ! \        R4      R7      pVP                  R	V4       VP                  ^
4       VP                  VR
R
^4       VP                  VR
R
^ 4       V'       g   TpV'       d   \!        V\        4      '       d   V.p	MTp	M. p	V	 F  p
SP#                  V
.4       K  	  \         P$                  ! 4       p\         P&                  ! SR7      p\         P(                  ! \        R4      V^ R7      pVP+                  V4       VP                  RV4       \         P,                  ! 4       pVP/                  ^4       VP                  ^
4       VP1                  \         P2                  P4                  4       VP7                  \         P8                  P:                  \         P8                  P:                  4       VP=                  V4       VP                  VRR^ 4       S P?                  WRR7      # )z"Generate a multiple file selector.c           	     s  < \         P                  P                  \        R4      R\         P                  P
                  \        R4      \        R4      4      pVP                  R4       S Uu. uF  q"^ ,          NK  	  ppV'       d'   \        P                  P                  V^ ,          4      MRpTP                  T;'       g    S	P                  4       VP                  4       pV\         P                  P                  8X  d_   VP                  4        F.  pWc9  g   K  SP!                  V.4       VP!                  V4       K0  	  S	P"                  P%                  SV4       VP'                  4        R# u upi )z)Create and run multi-file chooser dialog.zSelect filesNZ_AddZ_CancelT)r   ZFileChooserNativeZnewr   r   r   Zset_select_multiplerQ   rR   ZdirnameZset_current_folderrV   ZrunZResponseTypeZACCEPTZget_filenamesrf   r(   r   rv   )
r   ZdialogrowfilesZfirst_file_dirZresponsefilenamefiles_list_storerF   rD   s
   &      r   on_add_files_clickedZEWidgetGenerator._generate_multiple_file.<locals>.on_add_files_clicked3  s    **...!%%**&	)F &&t,'78'7VV'7E8:?RWW__U1X6TN%%n&N&N8N8NOzz|H3++222 & 4 4 6H,(//
;X. !7 !!*e4NN 9s   -E4c                sT  < VP                   \        P                  8X  d   V P                  4       pVP	                  4       w  r4V FX  pVP                  V4      pVP                  V4       S	 Uu. uF  qw^ ,          NK  	  ppSP                  P                  S
V4       KZ  	  R# R# u upi )z<Action triggered when a row is deleted from the filechooser.N)	Zkeyvalr   Z
KEY_DeleteZget_selectionZget_selected_rowsZget_iterZremover(   r   )ZtreeviewZeventZ	selectionmodelZ	treepathsZtreepathZtreeiterr   r   r   rF   rD   s   &&       r   on_files_treeview_keypressZKWidgetGenerator._generate_multiple_file.<locals>.on_files_treeview_keypressK  s    ||s~~-$224	%.%@%@%B" )H$~~h7HLL*/?@/?VV/?E@LL%%j%8 !* . As   .B%r]   r#   )r   Z:z	Add Filesr#   ZclickedF)r   ZFiles)r   zkey-press-eventTr   ) r   r   rI   r_   r   r   r   r   r   r   ZButtonr   r   Zset_margin_leftrh   Zpack_endrx   rf   r   ZTreeViewZTreeViewColumnZappend_columnZScrolledWindowZset_min_content_heightZset_shadow_typeZ
ShadowTypeZ	ETCHED_INZ
set_policyZ
PolicyTypeZ	AUTOMATICaddr   )rD   r]   r|   r{   r   r   r#   rg   Zbuttonr   r   Zcell_rendererZfiles_treeviewZfiles_columnZtreeview_scrollr   rF   s   f&&&           @@r   r?   Z'WidgetGenerator._generate_multiple_file0  s   	0
	9 H%
w==-ww3??#;#;<eck")!K.1y"67r"ueQ/feUA.E%%%EH##XJ/ ,,.,<=))!G*m!L$$\202LM,,...s3''+''(@(@A""3>>#;#;S^^=U=UVN+tQ7''t'DDr"   c                s  a a VV 3R lpVR,          o\        VP                  R4      4      pV'       g   Tp\        \        R4      \        P
                  P                  TTV'       g   S P                  MRR7      pVP                  RV4       VP                  \        P                  P                  4       S P                  W4      # )z5Generate a file chooser button to select a directory.c                r   r   r   r   r   r   r)   Z7WidgetGenerator._generate_directory.<locals>.on_changed  r   r"   r]   r   zSelect folderN)r   r   r   r   r   r(   )r$   rP   r   r   r   r   ZSELECT_FOLDERrV   r   r   r   r   r   )rD   r]   r|   r{   r)   r   Zdirectory_chooserrF   r   r   r@   Z#WidgetGenerator._generate_directory  s    	0
 H%
&*6::6S+T&U#E,O$((66(C7<//$
 	!!)Z8$$SYY%5%56''BBr"   c                sR  a a VV 3R lpVR,          oT;'       g    T;'       g    / p \        VP                  4       4      p\        VRR.R7      pVP                  RV4       S P                  W4      #   \         d'    \        P                  ! R\        T4      T4       / p Lbi ; i)zAdds an editable grid widgetc                 sr   < \        V P                  4       4      pSP                  P                  SV4       R # rY   )ZdictZget_datar(   r   )r   valuesrF   rD   r   r   r)   Z5WidgetGenerator._generate_mapping.<locals>.on_changed  s(    &//+,FLLj&1r"   r]   z2Invalid value of type %s passed to grid widget: %sZKeyZValue)Zcolumnsr(   )	listr   ZAttributeErrorr   r   rr   r   r   r   )rD   r]   r|   r{   r)   ZgridrF   r   r   rA   Z!WidgetGenerator._generate_mapping  s    	2 H%
&&&&B	'E
 EE7+;<Y
+''55  	LLMtTY{\abE	s   A5 5.B&%B&c                s    \        V4      pVP                  R4       VP                  ^<4       \        P                  ! 4       pVP                  V4       VP                  4        VP                  V4       R# )z+Prepare a custom tooltip with a fixed widthT)r   r   Zset_max_width_charsr   ZEventBoxr   rp   Z
set_custom)r   Z_xZ_yZ	_keybmoder   r   r#   Z	event_boxs   &&&&&&  r   r   Z WidgetGenerator.on_query_tooltip  s]     dT"!!"%LLN	e9%r"   c                s,   < V ^8  d   QhRS[ RS[RS[/# )r   rF   r{   r   rH   r   r   r   r    r!     s"     $ $c $C $C $r"   c                s    \        4       h)z^Reads the current value for a specific setting; this method must be
implemented by a subclass.)ZNotImplementedError)rD   rF   r{   rK   r   rt   ZWidgetGenerator.get_setting  s     "##r"   c                s<   < V ^8  d   QhRS[ S[S[3,          RS[/# r   r]   r   r   r   r   r   r    r!     s'     M M$sCx. MS Mr"   c                s*    V P                  RRVR7      # )zfReturns the default value from the option; if it is callable, this calls
it to get the actual default.r{   Nr{   r]   )r   r   rZ   r   rs   ZWidgetGenerator.get_default  s     $$YV$LLr"   c                <   < V ^8  d   QhRS[ S[S[3,          RS[/# r   r   rI   r   r$   r   r   r   r    r!     s#     = =T#s(^ = =r"   c                s&    V P                  RV4      # )zExtracts the 'visible' option; if the option is missing this returns
True, and if it is callable this calls it. Subclasses can add further conditions.rc   )r   r   rZ   r   r   ZWidgetGenerator.get_visibility  s     )))V<<r"   c                r   r   r   r   r   r   r    r!     s#      DcN t r"   c                s   V P                  RV4      pVP                  R4      pV'       d<   V P                  V P                  V,          4      pV P	                  W44      '       g   R# V P
                  VR,          ,          pVP                  4        F,  p\        VR4      '       g   K  VP                  '       g   K+   R# 	  V# )zExtracts the 'condition' option; but also the 'conditional_on' option, and if both
are present, then if either indicates the control should be disabled this will be false..r   conditional_onFr]   blocks_sensitivity)	r   rP   rs   r0   rt   r6   ru   r   r   )rD   r]   r   r   Zconditional_on_defaultr   r}   s   &&     r   r   ZWidgetGenerator.get_condition  s     ..{FC	$45%)%5%5dll>6R%S"##NKK**6(+;<	++-Eu2338P8P8P . r"   c                sB   < V ^8  d   QhRS[ RS[S[ S[3,          RS[/# )r   r   r]   r   )rI   r   r   r$   r   r   r   r    r!     s*     8 8 8d38n 8 8r"   c                sL    V P                  VRVR7      pVe   \        V4      # R# )zEvaluates a flag option; if is None or missing this returns True, and if
it is callable this calls it (as with _evaluate_option) and converts
the result to a bool.Tr   )r   r$   )rD   r   r]   Zflags   &&& r   r   Z%WidgetGenerator._evaluate_flag_option  s/     $$S$v$F!-tDz747r"   c                sH   < V ^8  d   QhRS[ RS[RS[S[ S[3,          RS[/# )r   r   r{   r]   r   )rI   r   r   r   r   r   r    r!     s8     @ @C @# @tCH~ @RU @r"   c                sF    W9  d   V# W1,          pV P                  WCR7      # )a  Evaluates an option; if is missing, then function returns 'default', and
if it is callable this calls it, passing the option key, generator's args and kwargs.

The callable may take fewer arguments; if so, this will pass as many argments
as it will take, even if that is none at all.)r]   )evaluate_option_value)rD   r   r{   r]   r|   r   r   r   Z WidgetGenerator._evaluate_option  s*     N))%)??r"   c                sB   < V ^8  d   QhRS[ RS[S[S[ 3,          RS[ /# )r   r|   r]   r   )r   r   rI   r   r   r   r    r!     s*      3 S#X 3 r"   c                s   \        V4      '       EdM   \        V4      p\        VP                  4      pVR,          p^\        V P                  4      ,           pWF8  d!   V! V.V P                  O5/ V P
                  B # \        ;QJ d4    R VP                  P                  4        4       F  '       g   K   RM)	  RM%! R VP                  P                  4        4       4      '       d!   V! V.V P                  O5/ V P
                  B # V^ 8X  d   V! R/ V P
                  B # \        V P                  4      pVP                  ^ V4       VRV pV! V/ V P
                  B # V# )a   Evaluates the 'value' given, if it is callable. If not, this method just
returns the 'value'.

The 'value' is called with the option-key and then all the callback arguments
given to this generator's __init__. If the 'value' takes fewer arguments than
this, trailing arguments are omitted.r]   c              3   sZ   "   T F!  qP                   \        P                  8H  x  K#  	  R # 5irY   )Zkindr   ZVAR_POSITIONAL).0ZprU   r   	<genexpr>Z8WidgetGenerator.evaluate_option_value.<locals>.<genexpr>  s     YAXAVVy777AXs   )+TFNr   )
callabler   ZlenZ
parametersr&   r'   anyr   r   r   )rD   r|   r]   ZsigZargcountrF   Z
argsneededZargss   &&&     r   r   Z%WidgetGenerator.evaluate_option_value  s&    E??E"C3>>*H)JS!3!344J%ZU$*<*<U@T@TUUYAVAVAXYYAVAVAXYYYZU$*<*<U@T@TUUQ4t3344D../Az*IXd;d&:&:;;r"   )r+   r,   r*   rC   r&   r'   r(   r.   r2   r6   r1   r0   r   r5   r/   r3   r-   r4   rY   )FT)F)5__name__
__module____qualname____firstlineno____doc__r   r   rI   r   r
   r   r`   ZGeneratorFunctionrE   r)   propertyrV   Zsetterrk   rd   rn   ry   r~   rz   rw   ro   r   rJ   r   r7   r8   r9   r:   r;   r<   r=   r>   rB   r?   r@   rA   Zstaticmethodr   r   rt   rs   r   r   r   r   r   __static_attributes____classdictcell__)r   s   @r   r   r      s    & !$sCx.#s!;Xcjj=Q!QR&
 &
P  ' ' * *
   0 .0 0dM M N N
j 
j   :/ /) ),F7!FH=(\:~M
:(>VOME`C46& 	 	 $ $
M M
= =
 &8 8@ @ r"   r   c                   s<   a a ] tR tRt oRtV 3R ltR tRtVtV ;t	# )re   i  zA frame that is styled to have particular margins, and can have its frame hidden.
This leaves the content but removes the margins and borders and all that, so it looks
like the frame was never there.c                s  < \         SV `  ! RR V/VB  Wn        \        P                  ! \        P
                  P                  RR7      V n        V P                  V P                  4       V P                  4       P                  R4       R# )r#   Tr   zsection-frameNr   )superrE   ra   r   r_   r   r   rg   r   Zget_style_contextZ	add_class)rD   ra   kwargs	__class__s   &&,r   rE   ZSectionFrame.__init__  s`    1w1&1GG(@(@$O	 **?;r"   c                s    \         ;QJ d4    R  V P                  P                  4        4       F  '       g   K   R# 	  R# ! R  V P                  P                  4        4       4      # )c              3   sT   "   T F  qP                  4       '       g   K  Vx  K   	  R # 5irY   Zget_visible)r   ZwrU   r   r   Z4SectionFrame.has_visible_children.<locals>.<genexpr>  s     J6--/116s   (
(TF)r   rg   ru   rD      &r   r   Z!SectionFrame.has_visible_children  sE    sJdii446JssJsJsJdii446JJJr"   )ra   rg   )
r   r   r   r   r   rE   r   r   r   __classcell__r   r      @@r   re   re     s     '<K Kr"   re   c                   sL   a a ] tR tRt oRtRV 3R lltV3R lR ltRtVtV ;t	# )WidgetWarningMessageBoxi  zHA box to display a message with an icon inside the configuration dialog.c           	     s  < \         SV `  ^RVVVRR7       \        P                  ! RR7      pVP	                  V\        P
                  P                  4       V P                  VRR^ 4       \        P                  ! R^ R7      V n	        V P                  P                  R4       V P                  V P                  RR^ 4       R# )   FT)r   rc   margin_leftmargin_rightr   Zno_show_allrb   )rc   ZxalignN)r   rE   r   ZImageZset_from_icon_nameZIconSizeZDNDrh   r   r#   Zset_line_wrap)rD   	icon_namer  r  r   Zimager   s   &&&&& r   rE   Z WidgetWarningMessageBox.__init__"  s    #%' 	 	
 		$'  CLL,<,<=ueQ/YYtA6


  &

E5!4r"   c                rL   rM   )r$   r   r   r   r    Z$WidgetWarningMessageBox.__annotate__3  s     	 	T 	r"   c                s    \        V4      pV'       d%   V P                  P                  \        V4      4       V P	                  V4       V# )zDisplays the markup given, and shows this box. If markup is empty or None,
this hides the box instead. Returns the new visibility.)r$   r#   
set_markuprI   r   )rD   Zmarkuprc   s   && r   show_markupZ#WidgetWarningMessageBox.show_markup3  s9     v,JJ!!#f+.!r"   r   )   r  r   )
r   r   r   r   r   rE   r  r   r   r   r   r   r   r   r     s     R5"	 	 	r"   r   c                   sD   a a ] tR tRt oV 3R ltV3R lR ltRtVtV ;t# )ConfigMessageBoxi?  c                s   < Wn         \        SV `  ! V3/ VB  \        V4      '       g<   \	        V4      pV'       d'   V P
                  P                  \        V4      4       R # R # R # rY   )messager   rE   r   r   r#   r  rI   )rD   r  r  r   r   r   s   &&&, r   rE   ZConfigMessageBox.__init__@  sR    -f-  G$D

%%c$i0  !r"   c                sB   < V ^8  d   QhRS[ S[S[3,          RS[RS[/# )r   r]   	generatorr   )r   rI   r   r   r$   r   r   r   r    ZConfigMessageBox.__annotate__J  s+     & &T#s(^ & &TX &r"   c                s     VP                  V P                  V4      pV P                  V4      #   \         d6   p\        P                  ! R T4       \        \        T4      4      p Rp?LLRp?ii ; i)z,Unable to generate configuration warning: %sN)r   r  Z	Exceptionr   Z	exceptionr   rI   r  )rD   r]   r	  r   Zerrrj   r   r   ZConfigMessageBox.update_messageJ  sa    	&224<<HD
 %%	  	&KSQCH%D	&s   / A/+A**A/)r  )	r   r   r   r   rE   r   r   r   r   r   r   r   r  r  ?  s     1& & &r"   r  c                   s2   a a ] tR tRt oV 3R ltRtVtV ;t# )r   iT  c                *   < \         SV `  VR R7       R# )zdialog-warningr  Nr   rE   )rD   r   r      &&r   rE   ZConfigWarningBox.__init__U  s    ,<=r"   r   )r   r   r   r   rE   r   r   r   r   r   r   r   r   T  s     > >r"   r   c                   sB   a a ] tR tRt oV 3R lt]R 4       tRtVtV ;t	# )r   iY  c                r
  )zdialog-errorr  Nr  )rD   r   r   r  r   rE   ZConfigErrorBox.__init__Z  s    .9r"   c                s"    V P                  4       # )zTCalled to check if the wrapper should be made insensitive
because of this error box.r   r   r   r   r   Z!ConfigErrorBox.blocks_sensitivity]  s     !!r"   r   )
r   r   r   r   rE   r   r   r   r   r   r   r   r   r   r   Y  s#     : " " "r"   r   ),r   rQ   Zabcr    r   r   r   Zinspectr   r   Ztypingr   r   r   r   r	   r
   Zgi.repositoryr   r   Zlutris.configr   Zlutris.gui.widgetsr   Zlutris.gui.widgets.commonr   r   r   Z&lutris.gui.widgets.searchable_entryboxr   Zlutris.util.logr   Zlutris.util.stringsr   Zlutris.gui.config.boxesr   r   ZFramere   r_   r   r  r   r   r   r"   r   <module>r     s    1 	 #   ( E E " & 1 K K E " (1vc vrK399 K cgg @&. &*>' >
"% "r"   