e fG@sdZddlTGdddeZGdddeZGdddeZGd d d eZd d Ze d krddl m Z e endS)aAn implementation of tabbed pages using only standard Tkinter. Originally developed for use in IDLE. Based on tabpage.py. Classes exported: TabbedPageSet -- A Tkinter implementation of a tabbed-page widget. TabSet -- A widget containing tabs (buttons) in one or more rows. )*c@seZdZdS)InvalidNameErrorN)__name__ __module__ __qualname__rr8/opt/alt/python34/lib64/python3.4/idlelib/tabbedpages.pyr s rc@seZdZdS)AlreadyExistsErrorN)rrrrrrrr s r c@seZdZdZddddddZdd Zd d Zd d ZddZddZ ddZ Gddde Z dS)TabSetzjA widget containing tabs (buttons) in one or more rows. Only one tab may be selected at a time. NFc Kstj|||||_||_||_||_||_i|_i|_|rjt ||_ n g|_ d|_ g|_ t|dddddt d|jd|_|jjdtd td d |jdS) aConstructor arguments: select_command -- A callable which will be called when a tab is selected. It is called with the name of the selected tab as an argument. tabs -- A list of strings, the names of the tabs. Should be specified in the desired tab order. The first tab will be the default and first active tab. If tabs is None or empty, the TabSet will be initialized empty. n_rows -- Number of rows of tabs to be shown. If n_rows <= 0 or is None, then the number of rows will be decided by TabSet. See _arrange_tabs() for details. max_tabs_per_row -- Used for deciding how many rows of tabs are needed, when the number of rows is not constant. See _arrange_tabs() for details. Nheight borderwidthrrelief backgroundsidefillexpandF)Frame__init__select_commandn_rowsmax_tabs_per_row expand_tabspage_set_tabs_tab2rowlist _tab_names _selected_tab _tab_rowsFLATcgetZ padding_framepackTOPX _arrange_tabs)selfrrZtabsrrrkwrrrrs$           zTabSet.__init__cCsY|std|n||jkr;td|n|jj||jdS)z.Add a new tab with the name given in tab_name.zInvalid Tab name: '%s'zTab named '%s' already existsN)rrr appendr')r(tab_namerrradd_tabDs zTabSet.add_tabcCs@||jkr"td|n|jj||jdS)zRemove the tab named zNo such Tab: '%sN)rKeyErrorremover')r(r+rrr remove_tabNszTabSet.remove_tabcCs||jkrdS|dk rA||jkrAtd|n|jdk rg|j|jjnd|_|dk r||_|j|}|j|j|}|j|jdtdt ddndS)z1Show the tab named as the selected oneNzNo such Tab: '%srrrr) r rr- set_normal set_selectedr pack_forgetr$r%r&)r(r+tabtab_rowrrrset_selected_tabVs       zTabSet.set_selected_tabcCs|s dSt|}|jdtdtdd|jj|xx|D]p}tj||j||}|r|jdt dtddn|jdt ||j |<||j |dS|jdk rh|jdkrh|j}nt|jd|jd}|jp|dk}d}xht |D]Z}t|j|d||d}|j|||}||7}|j ||qW|j }|j d||jkrA|j |ndS)aW Arrange the tabs in rows, in the order in which they were added. If n_rows >= 1, this will be the number of rows used. Otherwise the number of rows will be calculated according to the number of tabs and max_tabs_per_row. In this case, the number of rows may change when adding/removing tabs. r Nr) rpopitemr<r=rrlenrrranger:r r5)r(rriZ row_indexZn_tabsr9selectedrrrr's&    #   zTabSet._arrange_tabsc@sgeZdZdZdZddZddZddZd d Zd d Z d ddZ dS)zTabSet.TabButtonzA simple tab-like widget.rcCstj||d|jdt||_||_||_d|_t|d|d|j dddd d t d t d d dddd  |_ |j j dt dtdd|j|jdS)zConstructor arguments: name -- The tab's name, which will appear in its button. select_command -- The command to be called upon selection of the tab. It is called with the tab's name as an argument. rrFtextcommandpadxr padyr Z takefocusZ indicatoronZhighlightthicknessrZ selectcolorrrrTN)rrbwRAISEDnamertab_setr8Z Radiobutton _select_eventZFALSEZbuttonr$r7r& _init_masksr0)r(rJrr4rKrrrrs      zTabSet.TabButton.__init__cGs|j|jdS)asEvent handler for tab selection. With TabbedPageSet, this calls TabbedPageSet.change_page, so that selecting a tab changes the page. Note that this does -not- call set_selected -- it will be called by TabSet.set_selected_tab, which should be called when whatever the tabs are related to changes. N)rrJ)r(argsrrrrLs zTabSet.TabButton._select_eventcCs|jdddS)zAssume selected lookrBTN) _place_masks)r(rrrr1szTabSet.TabButton.set_selectedcCs|jdddS)zAssume normal lookrBFN)rO)r(rrrr0szTabSet.TabButton.set_normalc Cs|jj}|jjd}t|dddtd||_t|dddtd||_t|jd|jdt |j_ |jj j ddd|j dd|jd |jd t|dddtd||_ t|j d|jdt |j _ dS) Nrrrrxywidthrr )rKr pages_framer#rr"maskmsklrHrIZmlplacemskrmr)r(rrrrrrMs    zTabSet.TabButton._init_masksFcCs|j}|r||j7}n|jjd|ddddddddd dd dd dd | |jjd|ddd|j ddddd dd |jd dd | |jj}|r|j s|j|j|j|jkr||j8}n|j jd|ddddddddd dd |jd dd | |j j jd|j d|j d d |jd ||jd |jj dS)NZin_ZrelxgrPrZrelyg?rQZrelwidthrRZ relheightr r) rHrUrWrVrKrr8Z winfo_rootxZ winfo_widthrXrYlower)r(rBr rrrrrOs4           #zTabSet.TabButton._place_masksN) rrr__doc__rHrrLr1r0rMrOrrrrr6s      r6) rrrr[rr,r/r5r:r=r'rr6rrrrr s  ,     (r c@seZdZdZGdddeZGdddeZGdddeZGdd d eZd ed d d ddZ ddZ ddZ ddZ d S) TabbedPageSetajA Tkinter tabbed-pane widget. Constains set of 'pages' (or 'panes') with tabs above for selecting which page is displayed. Only one page will be displayed at a time. Pages may be accessed through the 'pages' attribute, which is a dictionary of pages, using the name given as the key. A page is an instance of a subclass of Tk's Frame widget. The page widgets will be created (and destroyed when required) by the TabbedPageSet. Do not call the page's pack/place/grid/destroy methods. Pages may be added or removed at any time using the add_page() and remove_page() methods. c@s@eZdZdZdZddZddZddZd S) zTabbedPageSet.Pagez{Abstract base class for TabbedPageSet's pages. Subclasses must override the _show() and _hide() methods. FcCst|dddt|_dS)Nrrr)rrIframe)r(rrrrr9szTabbedPageSet.Page.__init__cCs tdS)N)NotImplementedError)r(rrr_show<szTabbedPageSet.Page._showcCs tdS)N)r^)r(rrr_hide?szTabbedPageSet.Page._hideN)rrrr[ uses_gridrr_r`rrrrPage1s   rbc@s4eZdZdZdZddZddZdS)zTabbedPageSet.PageRemovezAPage class using the grid placement manager's "remove" mechanism.TcCs#|jjdddddtdS)Nrowrcolumnsticky)r]gridNSEW)r(rrrr_FszTabbedPageSet.PageRemove._showcCs|jjdS)N)r]Z grid_remove)r(rrrr`IszTabbedPageSet.PageRemove._hideN)rrrr[rar_r`rrrr PageRemoveBs  rhcsFeZdZdZdZfddZddZddZS) zTabbedPageSet.PageLiftz?Page class using the grid placement manager's "lift" mechanism.TcsIttj|j||jjdddddt|jjdS)Nrcrrdre)superr\PageLiftrr]rfrgrZ)r(r) __class__rrrPszTabbedPageSet.PageLift.__init__cCs|jjdS)N)r]Zlift)r(rrrr_UszTabbedPageSet.PageLift._showcCs|jjdS)N)r]rZ)r(rrrr`XszTabbedPageSet.PageLift._hide)rrrr[rarr_r`rr)rkrrjLs  rjc@s.eZdZdZddZddZdS)zTabbedPageSet.PagePackForgetzAPage class using the pack placement manager's "forget" mechanism.cCs|jjdtdddS)NrrT)r]r$BOTH)r(rrrr_]sz"TabbedPageSet.PagePackForget._showcCs|jjdS)N)r]r2)r(rrrr``sz"TabbedPageSet.PagePackForget._hideN)rrrr[r_r`rrrrPagePackForget[s  rmNr r Fc KsPtj|||||_i|_g|_d|_d|_|jddd|jdddt||_ |j j dddddt |jj r|j jddd|j jdddnt ||jd|d |d ||_|rx|D]}|j|qWn|jj dddddt |j|jdS) aConstructor arguments: page_names -- A list of strings, each will be the dictionary key to a page's widget, and the name displayed on the page's tab. Should be specified in the desired page order. The first page will be the default and first active page. If page_names is None or empty, the TabbedPageSet will be initialized empty. n_rows, max_tabs_per_row -- Parameters for the TabSet which will manage the tabs. See TabSet's docs for details. page_class -- Pages can be shown/hidden using three mechanisms: * PageLift - All pages will be rendered one on top of the other. When a page is selected, it will be brought to the top, thus hiding all other pages. Using this method, the TabbedPageSet will not be resized when pages are switched. (It may still be resized when pages are added/removed.) * PageRemove - When a page is selected, the currently showing page is hidden, and the new page shown in its place. Using this method, the TabbedPageSet may resize when pages are changed. * PagePackForget - This mechanism uses the pack placement manager. When a page is shown it is packed, and when it is hidden it is unpacked (i.e. pack_forget). This mechanism may also cause the TabbedPageSet to resize when the page is changed. NrZweightr rcrdrerrr)rr page_classpages _pages_order _current_page _default_pageZcolumnconfigureZ rowconfigurerTrfrgrar change_page_tab_setadd_page) r(parent page_namesrnrrrr)rJrrrrcs*         zTabbedPageSet.__init__cCs|std|n||jkr;td|n|j|j|j|<|jj||jj|t |jdkr||_ |j |ndS)z0Add a new page with the name given in page_name.zInvalid TabPage name: '%s'z!TabPage named '%s' already existsr N) rror rnrTrpr*rtr,r?rrrs)r( page_namerrrrus zTabbedPageSet.add_pagecCs||jkr"td|n|jj|t|jdkrl||jkru|jd|_qun d|_||jkr|j|jn|jj ||jj |}|j j dS)z2Destroy the page whose name is given in page_name.zNo such TabPage: '%srN) ror-rpr.r?rrrqrsrtr/r;r]r<)r(rxZpagerrr remove_pages zTabbedPageSet.remove_pagecCs|j|krdS|dk rA||jkrAtd|n|jdk rg|j|jjnd|_|dk r||_|j|jn|jj|dS)z/Show the page whose name is given in page_name.NzNo such TabPage: '%s')rqror-r`r_rtr5)r(rxrrrrss   zTabbedPageSet.change_page) rrrr[objectrbrhrjrmrruryrsrrrrr\ s  ;  r\c st}ttttjd|j\}}}}|jd||df|jdt|dddgdd d d j d t d t dt t jdjddddj t jdjddddj t jdjddj t|t|dddfdd}t|dddfdd}t |dd}|j dddd|j dddd|j ddj dd|jdS)Nz[x+]z+%d+%dzTest tabbed pagesrwZFoobarZBazrrrFrrrrCZFoorFZBarzAdd PagerDcsjjS)N)rugetr) entryPgNametabPagerrsz_tabbed_pages..z Remove PagecsjjS)N)ryr}r)r~rrrrszname of page to add/remove:rEr )ZTkrmapintresplitZgeometrytitler\r$r%ZTRUErlZLabelror]ZEntryZButtonZmainloop) rvrootrRr rPrQZ buttonAddZ buttonRemoveZ labelPgNamer)r~rr _tabbed_pagess* 3  &&  r__main__)runN) r[Ztkinter Exceptionrr rr r\rrZidlelib.idle_test.htestrrrrr s