
    f0                         d Z ddlmZmZmZ ddlmZmZ ddlm	Z	  e	       Z
 G d de      Z G d d      Z G d	 d
e      Z G d de      Z G d de      Zy)z) Classes for recursive layout definition     )divisionprint_functionunicode_literals)RectTreeItem)Configc                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z
y)
KeyContextzN
    Transforms logical coordinates to canvas coordinates and vice versa.
    c                 v    t        dddd      | _        t        dddd      | _        t        dddd      | _        y )N              ?)r   initial_log_rectlog_rectcanvas_rectselfs    0/usr/lib/python3/dist-packages/Onboard/Layout.py__init__zKeyContext.__init__%   s@     !%S#sC 8 S#sC0  S#s3    c                 r    dj                  t        | j                        t        | j                              S )Nzlog={} canvas={})formatlistr   r   r   s    r   __repr__zKeyContext.__repr__0   s0    !((dmm)<*.t/?/?*@B 	Br   c                 R    | j                  |d         | j                  |d         fS Nr      )log_to_canvas_xlog_to_canvas_yr   coords     r   log_to_canvaszKeyContext.log_to_canvas4   0    $$U1X.$$U1X.0 	0r   c                    |j                         r
t               S t        | j                  |j                        | j	                  |j
                        | j                  |j                        | j                  |j                              S N)
is_emptyr   r   xr   yscale_log_to_canvas_xwscale_log_to_canvas_yhr   rects     r   log_to_canvas_rectzKeyContext.log_to_canvas_rect8   sf    ==?6MD((0((0..tvv6..tvv68 	8r   c                     | j                   }| j                  }|j                  ||j                  z
  |j                  z  |j                  z  z   S r$   r   r   r&   r)   r   r&   r   r   s       r   r   zKeyContext.log_to_canvas_x@   ?    &&==}}HJJ+--?(**LLLr   c                     | j                   }| j                  }|j                  ||j                  z
  |j                  z  |j                  z  z   S r$   r   r   r'   r+   r   r'   r   r   s       r   r   zKeyContext.log_to_canvas_yE   r2   r   c                 R    | j                  |d         | j                  |d         fS r   )r(   r*   r   s     r   scale_log_to_canvaszKeyContext.scale_log_to_canvasJ   s0    **584**5846 	6r   c                 b    || j                   j                  z  | j                  j                  z  S r$   )r   r)   r   r   r&   s     r   r(   z KeyContext.scale_log_to_canvas_xN   &    4##%%%77r   c                 b    || j                   j                  z  | j                  j                  z  S r$   )r   r+   r   r   r'   s     r   r*   z KeyContext.scale_log_to_canvas_yQ   r:   r   c                 R    | j                  |d         | j                  |d         fS r   )canvas_to_log_xcanvas_to_log_yr   s     r   canvas_to_logzKeyContext.canvas_to_logU   r"   r   c                     t        | j                  |j                        | j                  |j                        | j                  |j                        | j                  |j                              S r$   )	r   r>   r&   r?   r'   scale_canvas_to_log_xr)   scale_canvas_to_log_yr+   r,   s     r   canvas_to_log_rectzKeyContext.canvas_to_log_rectY   sV    D((0((0..tvv6..tvv68 	8r   c                     | j                   }| j                  }||j                  z
  |j                  z  |j                  z  |j                  z   S r$   r0   r1   s       r   r>   zKeyContext.canvas_to_log_x_   @    &&==KMM!XZZ/+--?(**LLr   c                     | j                   }| j                  }||j                  z
  |j                  z  |j                  z  |j                  z   S r$   r4   r5   s       r   r?   zKeyContext.canvas_to_log_yd   rF   r   c                 b    || j                   j                  z  | j                  j                  z  S r$   )r   r)   r   r9   s     r   rB   z KeyContext.scale_canvas_to_log_xj   &    4==??"T%5%5%7%777r   c                 b    || j                   j                  z  | j                  j                  z  S r$   )r   r+   r   r<   s     r   rC   z KeyContext.scale_canvas_to_log_ym   rI   r   c                     |j                         }| j                  }| j                  }|j                  D ]B  \  }}t	        dt        |      d      D ]$  } |||         ||<    |||dz            ||dz   <   & D |S )Nr      r   )copyr   r   segmentsrangelen)r   pathresultr   r   opcoordsis           r   log_to_canvas_pathzKeyContext.log_to_canvas_pathp   s    .... // 	;JB1c&k1- ;-fQi8q	-fQqSk:qs;	; r   c                    | j                   }| j                  }|j                  |d   |j                  z
  |j                  z  |j                  z  z   |j                  |d   |j                  z
  |j
                  z  |j
                  z  z   fS r   )r   r   r&   r)   r'   r+   r   r    r   r   s       r   r!   zKeyContext.log_to_canvas|   s    &&==}}a8:: 5(]] +-5ZZ 8 8}}a8:: 5(]] +-5ZZ 8 88 	8r   c                    |j                   }|j                  }|dk  s|dk  r
t               S | j                  }| j                  }|j                   |j                   z  }|j                  |j                  z  }t        |j
                  |j
                  |j
                  z
  |z  z   |j                  |j                  |j                  z
  |z  z   ||z  ||z        S )z ~50% faster than the above. r   )r)   r+   r   r   r   r&   r'   )r   r-   r)   r+   r   r   scale_wscale_hs           r   r.   zKeyContext.log_to_canvas_rect   s    FFFF6Q!V6M&&==--(**,--(**,KMMTVVhjj%8G$CCMMTVVhjj%8G$CCKK! 	!r   c                     | j                   }| j                  }|d   |j                  z  |j                  z  |d   |j                  z  |j                  z  fS r   )r   r   r)   r+   rX   s       r   r7   zKeyContext.scale_log_to_canvas   sR    &&==Qx+--'(**4Qx+--'(**45 	5r   N)__name__
__module____qualname____doc__r   r   r!   r.   r   r   r7   r(   r*   r@   rD   r>   r?   rB   rC   rV    r   r   r
   r
   !   sk    	4B08M
M
68808M
M888!"5r   r
   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd ZddZd Zd ZddZd Zd Zd Zd Zd Zd Zy)
LayoutRootz
    Decorator class wrapping the root item.
    Implements extensive caching to avoid most of the expensive
    (for python) traversal of the layout tree.
    c                 b    || j                   d<   | j                          | j                          y )N_item)__dict__invalidate_cachesinit_chamfer_sizesr   items     r   r   zLayoutRoot.__init__   s(    !%g !r   c                 .    t        | j                  |      S r$   )getattrre   )r   names     r   __getattr__zLayoutRoot.__getattr__   s    tzz4((r   c                 <    | j                   j                  ||       y r$   )re   __setattr__)r   rm   values      r   rp   zLayoutRoot.__setattr__   s    

tU+r   c                 D    | j                          | j                          y r$   )invalidate_traversal_cachesinvalidate_geometry_cachesr   s    r   rg   zLayoutRoot.invalidate_caches   s    ((*'')r   c                 f    i | _         i | _        i | _        i | _        i | _        i | _        d | _        y r$   )_cached_items_cached_keys_cached_visible_items_cached_layer_items_cached_layer_keys_cached_key_groups_cached_layer_idsr   s    r   rs   z&LayoutRoot.invalidate_traversal_caches   s<    %'"#% "$"$ "&r   c                 .    i | _         d | _        d | _        y r$   )_cached_hit_rects_last_hit_args_last_hit_keyr   s    r   rt   z%LayoutRoot.invalidate_geometry_caches   s    !#"!r   c                 Z    | j                   j                  |       | j                          y r$   )re   fit_inside_canvasrt   r   canvas_border_rects     r   r   zLayoutRoot.fit_inside_canvas   s#    

$$%78 	'')r   c                 Z    | j                   j                  |       | j                          y r$   )re   do_fit_inside_canvasrt   r   s     r   r   zLayoutRoot.do_fit_inside_canvas   s#    

''(:; 	'')r   c                 Z    | j                          | j                  j                  |       y)zV
        Show all items of layer "layer", hide all items of the other layers.
        N)rg   re   set_visible_layersr   	layer_idss     r   r   zLayoutRoot.set_visible_layers   s"     	 

%%i0r   c                 f    |j                   |k7  r"|j                  |       | j                          y y r$   )visibleset_visiblerg   )r   rj   r   s      r   set_item_visiblezLayoutRoot.set_item_visible   s-    <<7"W%""$ #r   c                 v    | j                   }|s*t        | j                  j                               }|| _         |S r$   )rv   tuplere   
iter_itemsr   itemss     r   r   zLayoutRoot.iter_items   s4    ""$**//12E!&Dr   Nc                     | j                   j                  |      }|s3t        | j                  j	                  |            }|| j                   |<   |S r$   )rw   getr   re   	iter_keys)r   
group_namer   s      r   r   zLayoutRoot.iter_keys   sI    !!%%j1$**..z:;E,1Dj)r   c                 v    | j                   }|s*t        | j                  j                               }|| _         |S r$   )rx   r   re   iter_visible_itemsr   s     r   r   zLayoutRoot.iter_visible_items   s4    **$**779:E).D&r   c                     | j                   j                  |      }|s3t        | j                  j	                  |            }|| j                   |<   |S )z
        Returns cached visible keys per layer, re-creates cache if necessary.
        Use iter_layer_keys if performance doesn't matter.
        )rz   r   r   re   iter_layer_keys)r   layer_idr   s      r   r   zLayoutRoot.iter_layer_keys   sK    
 ''++H5$**44X>?E05D##H-r   c                     ||f}| j                   j                  |      }|s1t         | j                  j                  |       }|| j                   |<   |S r$   )ry   r   r   re   iter_layer_items)r   r   only_visibleargsr   s        r   r   zLayoutRoot.iter_layer_items   sV    ,'((,,T25$**55t<=E-2D$$T*r   c                 d    | j                   }|s!| j                  j                         }|| _         |S r$   )r|   re   get_layer_idsr   s     r   r   zLayoutRoot.get_layer_ids  s0    **	

002I%.D"r   c                 d    | j                   }|s!| j                  j                         }|| _         |S )z2
        Return all keys sorted by group.
        )r{   re   get_key_groups)r   
key_groupss     r   r   zLayoutRoot.get_key_groups  s2     ,,
224J&0D#r   c                 8   ||f}| j                   |k(  r| j                  S d}|\  }}| j                  |      }|D ]O  \  }}	}
}}||k\  s||
k  s||	k\  s||k  s!|j                   |j	                         j                  |      sM|} n || _         || _        |S )z0
        Find the topmost key at point.
        N)r   r   _get_hit_rectsgeometryget_hit_pathis_point_within)r   pointactive_layerr   keyr&   r'   	hit_rectsx0y0x1y1ks                r   
get_key_atzLayoutRoot.get_key_at  s     |$$&%%%1''5	!* 	BBABw1r6Bw1r6::%>>#33E:C	 # 
r   c                 t   	 | j                   |   }|S # t        $ r | j                  }t        t	        t         ||                        t        t	        t         |d                         z   }|D cg c]$  }|j                         j                         |fz   & nc c}w }}|| j                   |<   Y |S w xY wr$   )r~   KeyErrorr   r   reversedget_hit_rect
to_extents)r   r   r   r   r   rj   s         r   r   zLayoutRoot._get_hit_rects1  s    	=..|<I   
	= #22O$|'D"EFG$t'<"=>?@E "'( **,779TGC ( (I (3<D""<0
	=s    A B73)BB76B7c                     | j                         }| j                         D ]:  }|j                  |j                         }|j	                  |      }|4||_        < y r$   )_calc_chamfer_sizesiter_global_keyschamfer_size	get_layerr   )r   chamfer_sizesr   r   r   s        r   rh   zLayoutRoot.init_chamfer_sizesB  s]    002((* 	4C'==?,00:#+'3C$	4r   c                    i }d g| j                         z   D ]  }i }| j                  |      D ]J  }|j                         }t        |j                  |j
                        }|j                  |d      dz   ||<   L |rOt        t        t        t        |j                               t        |j                                                 d   nd }||dz  nd }|||<    |S )Nr   r   g      ?)r   r   get_border_rectminr)   r+   r   maxr   zipvalueskeys)	r   r   r   histr   rsmost_frequent_sizer   s	            r   r   zLayoutRoot._calc_chamfer_sizesK  s    !3!3!55 	3HD++H5 -'')QSSM((1a.1,Q-  DT$++-0$tyy{2CDEFqI!  *1 .37; &2M(#	3 r   r$   )NT)r]   r^   r_   r`   r   rn   rp   rg   rs   rt   r   r   r   r   r   r   r   r   r   r   r   r   r   rh   r   ra   r   r   rc   rc      sp    
"
),*
&"**1%
	6"4r   rc   c                      e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdZdZdZdZd Zd Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d Z)d Z*d Z+d Z,d Z-d Z.d  Z/d! Z0d" Z1d# Z2d8d$Z3d% Z4d& Z5d' Z6d( Z5d) Z7d* Z8d+ Z9d, Z:d8d-Z;d. Z<d8d/Z=d8d0Z>	 	 d9d1Z?d2 Z@d3 ZAd4 ZBd5 ZCd6 ZDd7 ZEy):
LayoutItemz* Abstract base class for layoutable items NTr   c                 "    t               | _        y r$   )r
   contextr   s    r   r   zLayoutItem.__init__  s    !|r   c                 r    dj                  t        |       j                  t        | j                              S )Nz{}({}))r   typer]   repridr   s    r   r   zLayoutItem.__repr__  s%    tDz22DMBBr   c           
         dt               vrdat        dz  adt        z  dj                  t        j	                  |       t        | j                        t        | j                        t        | j                        t        | j                              z   dj                  d | j                  D              z   }t        dz  a|S )zs
        Recursively dumps the layout (sub-) tree starting from self.
        Returns a multi-line string.
        _levelr   z   z"{} id={} layer_id={} fn={} vis={}
 c              3   <   K   | ]  }|j                           y wr$   )dumps.0rj   s     r   	<genexpr>z#LayoutItem.dumps.<locals>.<genexpr>  s     ;tzz|;s   )globalsr   r   objectr   r   r   r   filenamer   joinr   )r   r   s     r   r   zLayoutItem.dumps  s     79$F!&L@GG"(//$"7"&tww-"&t}}"5"&t}}"5"&t||"4$ $ ww;

;;< 	!r   c                     || _         y r$   )r   )r   r   s     r   set_idzLayoutItem.set_id  s	    r   c                 T    | j                         j                  | j                        S )z) Get bounding box in logical coordinates )r   deflateborderr   s    r   get_rectzLayoutItem.get_rect  s     ##%--dkk::r   c                 .    | j                   j                  S )z; Get bounding rect including border in logical coordinates r   r   r   s    r   r   zLayoutItem.get_border_rect  s    ||$$$r   c                 &    || j                   _        y)z; Set bounding rect including border in logical coordinates Nr   r   border_rects     r   set_border_rectzLayoutItem.set_border_rect  s     +r   c                 .    | j                   j                  S )zS
        Get initial bounding rect including border in logical coordinates
        r   r   r   s    r   get_initial_border_rectz"LayoutItem.get_initial_border_rect  s     ||,,,r   c                 &    || j                   _        y)zT
        Set initial bounding rect including border in logical coordinates.
        Nr   r   s     r   set_initial_border_rectz"LayoutItem.set_initial_border_rect  s     )4%r   c                 T    | j                   j                  | j                               S )z( Get bounding box in canvas coordinates )r   r.   r   r   s    r   get_canvas_rectzLayoutItem.get_canvas_rect  s    ||..t}}??r   c                 .    | j                   j                  S )z: Get bounding rect including border in canvas coordinates r   r   r   s    r   get_canvas_border_rectz!LayoutItem.get_canvas_border_rect  s    ||'''r   c                 J    | j                         }|d   t        |d         z  S )zd
        Return the aspect ratio of the visible logical extents
        of the layout tree.
        r   r   )get_log_extentsfloatr   sizes     r   get_log_aspect_ratiozLayoutItem.get_log_aspect_ratio  s)    
 ##%AwtAw''r   c                 >    | j                         j                         S )
        Get the logical extents of the layout tree.
        Extents ignore invisible, "collapsed" items,
        ie. an invisible click column is not included.
        )r   get_sizer   s    r   r   zLayoutItem.get_log_extents  s     ##%..00r   c                 X    | j                         }| j                  j                  |      S )z<
        Get the canvas extents of the layout tree.
        )r   r   r7   r   s     r   get_canvas_extentszLayoutItem.get_canvas_extents  s'     ##%||//55r   c                 X    | j                         }|j                  j                  d      S )z; Account for stroke width and antialiasing of keys and bars)       @r  )get_layout_rootr   r7   )r   roots     r   get_extra_render_sizez LayoutItem.get_extra_render_size  s%    ##%||//
;;r   c                 F    | j                          | j                  |       yzR
        Scale item and its children to fit inside the given canvas_rect.
        N)update_log_rectr   r   s     r   r   zLayoutItem.fit_inside_canvas  s!    
 	 	!!"45r   c                 &    || j                   _        yr  r   r   s     r   r   zLayoutItem.do_fit_inside_canvas  s     $6 r   c                 N    | j                         D ]  }|j                           y r$   )iter_depth_first_update_log_rectri   s     r   r  zLayoutItem.update_log_rect  s&    ))+ 	$D!!#	$r   c                      y)zh
        Override this for layout items that have to calculate their
        logical rectangle.
        Nra   r   s    r   r  zLayoutItem._update_log_rect  s    
 	r   c                 @    | j                         j                  d      S ): Returns true if the point lies within the items borders. r   )r   inflater   s    r   r   zLayoutItem.get_hit_rect  s    **,44Q77r   c                 D    | j                         }|j                  |      S )r  )r   r   )r   canvas_pointr-   s      r   r   zLayoutItem.is_point_within  s!      "##L11r   c                     || _         y r$   r   )r   r   s     r   r   zLayoutItem.set_visible  s	    r   c                     | j                   S )z Returns visibility status r  r   s    r   
is_visiblezLayoutItem.is_visible  s    ||r   c                 D    | }|r|j                   sy|j                  }|ry)z0 Are all items in the path to the root visible? FT)r   parentri   s     r   is_path_visiblezLayoutItem.is_path_visible  s'    <<;;D  r   c                 R    | j                         D ]  }|j                         s y y)z]
        Checks if there is any visible key in the
        subtree starting at self.
        TF)r   is_keyri   s     r   has_visible_keyzLayoutItem.has_visible_key%  s-    
 ++- 	D{{}	 r   c                 D    | }|r|j                   sy|j                  }|ry)z2 Are all items in the path to the root scannable? FT)	scannabler  ri   s     r   is_path_scannablezLayoutItem.is_path_scannable/  s'    >>;;D  r   c                 Z    | }|r'|j                   |j                   S |j                  }|r'y)z< Return the closeset scan_priority in the path to the root. r   )scan_priorityr  ri   s     r   get_path_scan_priorityz!LayoutItem.get_path_scan_priority8  s5    %%-)));;D  r   c                 H    | }|r|j                   |S |j                   }|ryyz Return the root layout item Nr  ri   s     r   r  zLayoutItem.get_layout_rootA  '    {{";;D r   c                 H    | }|r|j                   |S |j                   }|ryyr$  r%  ri   s     r   get_global_layout_rootz!LayoutItem.get_global_layout_rootI  r&  r   c                 `    d}| }|r'|j                   |j                   }|j                  }|r'|S )zB Return the first layer_id on the path from the tree root to self N)r   r  r   r   rj   s      r   r   zLayoutItem.get_layerQ  s7    ==(==;;D  r   c                     | j                   #| j                         s| j                   |v | _        | j                  D ]  }|j	                  |        y)z[
        Show all items of layers <layer_ids>, hide all items of the other layers.
        N)r   r  r   r   r   )r   r   rj   s      r   r   zLayoutItem.set_visible_layers[  sH     }}$;;=#}}	9JJ 	/D##I.	/r   c                     |g }| j                   )| j                   |vr|j                  | j                          | j                  D ]  }|j                  |        |S )zV
        Search the tree for layer ids and return them in order of appearance
        )r   appendr   r   )r   
_layer_idsrj   s      r   r   zLayoutItem.get_layer_idsf  s`     J}}$}}
*dmm,JJ 	+Dz*	+ r   c                     i }| j                         D ]>  }|j                  |j                  g       }|j                  |       |||j                  <   @ |S )zH
        Traverse the tree and return all keys sorted by group.
        )r   r   groupr-  )r   r   r   r   s       r   r   zLayoutItem.get_key_groupsv  sU     
>># 	)C>>#))R0DKK$(Jsyy!	) r   c                     | j                   rK| j                   j                  j                  |        | j                   j                  j                  |        yy)z' raise self to the top of its siblings Nr  r   remover-  r   s    r   raise_to_topzLayoutItem.raise_to_top  s>    ;;KK$$T*KK$$T* r   c                     | j                   rL| j                   j                  j                  |        | j                   j                  j                  d|        yy)z* lower self to the bottom of its siblings r   N)r  r   r3  insertr   s    r   lower_to_bottomzLayoutItem.lower_to_bottom  s@    ;;KK$$T*KK$$Q- r   c                     | j                   rK| j                   j                  j                  |        | j                   j                  j                  |        y y r$   r2  r   s    r   r4  zLayoutItem.raise_to_top  s>    ;;KK$$T*KK$$T* r   c                     | j                   r| j                   S | j                  r| j                  j                         S y)zP
        Recursively finds the closeset definition of the svg filename.
        N)r   r  get_filenamer   s    r   r:  zLayoutItem.get_filename  s2     ==== ;;;;++--r   c                     | j                   | j                   S | j                  r| j                  j                         S y)zc
        Recursively finds the closeset definition of the
        unlatch_layer attribute.
        N)unlatch_layerr  can_unlatch_layerr   s    r   r=  zLayoutItem.can_unlatch_layer  s9    
 !!)%%%;;;;0022r   c                      y)z  Returns true if self is a key. Fra   r   s    r   r  zLayoutItem.is_key  s    r   c              #      K   | j                   r/|  | j                  D ]  }|j                         D ]  }|   yyw)z}
        Traverses top to bottom all visible layout items of the
        layout tree. Invisible paths are cut short.
        N)r   r   r   )r   rj   visible_items      r   r   zLayoutItem.iter_visible_items  sJ     
 <<J

 '$($;$;$= 'L&&''	 s   =?c              #      K   | j                         r|j                  |k(  r|  | j                  D ]  }|j                  |      D ]  }|   yw)z?
        Iterates through all keys of the layout tree.
        N)r  r0  r   r   r   r   r   rj   s       r   r   zLayoutItem.iter_keys  sW      ;;=!SYY*%<
JJ 	D~~j1 		s   AAc              #      K   |  | j                   D ]  }|j                         D ]  }|   | j                  r+| j                  D ]  }|j                         D ]  }|   yyw)zN
        Iterates through all items of the tree including sublayouts.
        N)r   iter_global_items
sublayouts)r   rj   childs      r   rD  zLayoutItem.iter_global_items  s{      
JJ 	D//1 	 ??  !335  EK   s   A'A)c              #     K   | j                         r|j                  |k(  r|  | j                  D ]  }|j                  |      D ]  }|   | j                  r,| j                  D ]  }|j                  |      D ]  }|   yyw)zT
        Iterates through all keys of the layout tree including sublayouts.
        N)r  r0  r   r   rE  rB  s       r   r   zLayoutItem.iter_global_keys  s      ;;=!SYY*%<
JJ 	D,,Z8 		 ?? 00< CI s   B
Bc              #   b   K   | j                  |      D ]  }|j                         s|  yw)z?
        Iterates through all keys of the given layer.
        N)r   r  r*  s      r   r   zLayoutItem.iter_layer_keys  s0      ))(3 	D{{}
	s   %//c              #      K   |r| j                   sy| j                  |k(  r|}| j                  r| j                  |k7  ry||k(  r|  | j                  D ]  }|j                  |||      D ]  }|    yw)z
        Iterate through all items of the given layer.
        The first layer definition found in the path to each key wins.
        layer=None iterates through all keys that don't have a layer
        specified anywhere in their path.
        N)r   r   r   r   )r   r   r   _found_layer_idrj   s        r   r   zLayoutItem.iter_layer_items  s      ==H$&O==T]]o=h&JJJ 	D--h.=? 
	s   A4A6c                 F    | }|rt        ||      r|S |j                  }|ry)zC Find an item of a certain type in the path from self to the root. N)
isinstancer  )r   	classinforj   s      r   find_instance_in_pathz LayoutItem.find_instance_in_path  s,    $	*;;D  r   c                 h    |r0| j                   || _         y | j                   j                  |       y y r$   )	templatesupdate)r   rP  s     r   update_templateszLayoutItem.update_templates  s-    ~~%!*%%i0	 r   c                 h    |r0| j                   || _         y | j                   j                  |       y y r$   )keysym_rulesrQ  )r   rT  s     r   update_keysym_ruleszLayoutItem.update_keysym_rules  s2      ($0!!!((6	 r   c                 f    |r/| j                   g | _         | j                   j                  |       y y r$   )rE  r-  )r   	sublayouts     r   append_sublayoutzLayoutItem.append_sublayout  s-    &"$OO""9- r   c                     | j                         D ]-  }|j                  }|s|D ]  }|j                  |k(  s|c c S  / y)zJ
        Look for a sublayout item upwards from self to the root.
        N)iter_to_rootrE  r   )r   r   rj   rE  rW  s        r   find_sublayoutzLayoutItem.find_sublayout#  sN     %%' 	)DJ!+ )I ||r)(()	) r   c              #   X   K   | }|r"| |j                   xs |j                  }|r!yyw)z
        Iterate through sublayouts all the way to the global layout root.
        LayoutLoader needs this to access key templates from inside of
        sublayouts.
        N)r  sublayout_parentri   s     r   iter_to_global_rootzLayoutItem.iter_to_global_root/  s.      J;;7$"7"7D s   %**r$   )NTN)Fr]   r^   r_   r`   r0  ignore_groupr   r   r   r   	sensitiver   expandrE  r]  r<  r  r!  rP  rT  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r  r  r   r   r   r  r  r  r  r"  r  r(  r   r   r   r   r4  r7  r:  r=  r  r   r   rD  r   r   r   rN  rR  rU  rX  r[  r^  ra   r   r   r   r   ]  s   4 E L H H G G I F F J  M I M IL$C(;%,-4@((16<
66$82
	/ 	+.+	'
 " @D04217.
	8r   r   c                   H     e Zd ZdZdZdZdZd
 fd	Zd Zd Z	d Z
d	 Z xZS )	LayoutBoxzz
    Container for distributing items along a single horizontal or
    vertical axis. Items touch, but don't overlap.
    Tr   Fc                 X    t         t        |           | j                  |k7  r|| _        y y r$   )superrc  r   
horizontal)r   rf  	__class__s     r   r   zLayoutBox.__init__J  s(    i')??j((DO )r   c                 B    | j                         | j                  _        y r$   _calc_boundsr   r   r   s    r   r  zLayoutBox._update_log_rectO       $ 1 1 3r   c                     | j                   }d}| j                  D ]H  }|r|j                  s|j                         }|j	                         r3||}8|j                  |      }J |
t               S |S )z
        Calculate the bounding rectangle over all items of this panel.
        Include invisible items to stretch the visible ones into their
        space too.
        N)compactr   r   r   r%   unionr   r   rm  boundsrj   r-   s        r   rj  zLayoutBox._calc_boundsR  sp     ,,JJ 	4Ddll++-}}~!%!'d!3	4 >6Mr   c                    t         j                  | |       | j                  rdnd}| j                  }| j	                         }d}t        |      D ]B  \  }}|j                         }|j                         r'|r|| j                  z  }|||dz      z  }D |r||dz      |z  nd}	|	| j                  z  }
d}d}d}d}t        |      D ]U  \  }}|j                         |dz      }|s|j                         s0||	z  }|j                  r||z  }|dz  }L||z  }|dz  }W ||dz      |z
  |
||z   dz
  z  z
  }|r||z  nd}d}t        |      D ]  \  }}|j                         }|j                         r||dz      }|
}nd}d}|	}|j                  r||z  }||z  }t        | }||   |z   ||<   |||dz   <   |j                  |       |||z   z  } y)z1 Scale items to fit inside the given canvas_rect r   r   r   rL   r   N)r   r   rf  r   r   	enumerater   r%   spacingr  ra  r   )r   r   axisr   r   lengthrU   rj   r-   fully_visible_scalecanvas_spacinglength_expandablesnum_expandableslength_nonexpandablesnum_nonexpandableslength_targetexpandable_scalepositionrs  scalecanvas_lengthr   s                         r   r   zLayoutBox.do_fit_inside_canvasg  sZ    	''.@AOOq

 **,  ' 	'GAt'')D==?dll*F$tAv,&	' "( *$q&1F:-0 	,t||;
 ! # ' 		,GAt))+DF3F$..0--;;&&0&#q(O)V3)&!+&		, $DF+.CC!%7/%IA%MNO 1 )+==69 	
  ' 	0GAt'')D##%tAv,('E{{))"UNM k"A#D)H4AdG%Ad1fI%%a(//H)	0r   c                 $   d}| j                   D ]p  }|j                         }||j                         }&| j                  r |xj                  |j                  z  c_        R|xj
                  |j
                  z  c_        r |j                         S )r   N)r   r   rM   rf  r)   r+   r   )r   r-   rj   r   s       r   r   zLayoutBox.get_log_extents  sq     JJ 	"D$$&A|vvx??FFaccMFFFaccMF	" }}r   )T)r]   r^   r_   r`   rf  rs  rm  r   r  rj  r   r   __classcell__)rg  s   @r   rc  rc  ;  s8     J G G)
4*M0^r   rc  c                   &    e Zd ZdZdZd Zd Zd Zy)LayoutPanelzL
    Group of keys layed out at fixed positions relative to each other.
    Fc                    t         j                  | |       | j                         j                         r+| j                  D ]  }t               |j                  _         yt               }| j                         |_	        | j                         |_        | j                  D ]8  }|j                  |j                  j                        }|j                  |       : y)zB
        Scale panel to fit inside the given canvas_rect.
        N)r   r   r   r%   r   r   r   r   r
   r   r   r.   )r   r   rj   r   r-   s        r   r   z LayoutPanel.do_fit_inside_canvas  s     	''.@A !**,

 2+/6(2 !lG#335G"&"6"6"8G

 011$,,2G2GH))$/0r   c                 B    | j                         | j                  _        y r$   ri  r   s    r   r  zLayoutPanel._update_log_rect  rk  r   c                 4   t        d | j                  D              r
t               S | j                  }d}| j                  D ]H  }|r|j                  s|j                         }|j                         r3||}8|j                  |      }J |
t               S |S )z? Calculate the bounding rectangle over all items of this panel c              3   >   K   | ]  }|j                            y wr$   )r  r   s     r   r   z+LayoutPanel._calc_bounds.<locals>.<genexpr>  s     <4??$$<s   N)allr   r   rm  r   r   r%   rn  ro  s        r   rj  zLayoutPanel._calc_bounds  s     <<<6M,,JJ 	4Ddll++-}}~!%!'d!3	4 >6Mr   N)r]   r^   r_   r`   rm  r   r  rj  ra   r   r   r  r    s    
 G0(4r   r  N)r`   
__future__r   r   r   Onboard.utilsr   r   Onboard.Configr   configr   r
   rc   r   rc  r  ra   r   r   <module>r     se   * 0 A A ( "	x5 x5v~ ~B[8 [8|L
 L^2* 2r   