blob: 25a5143a08b4625ccc686a2cb2427a455c1cc763 [file] [log] [blame]
Steven M. Gava5b357b92001-12-05 06:32:46 +00001##---------------------------------------------------------------------------##
2##
3## pyChing -- a Python program to cast and interpret I Ching hexagrams
4##
5## Copyright (C) 1999,2000 Stephen M. Gava
6##
7## This program is free software; you can redistribute it and/or modify
8## it under the terms of the GNU General Public License as published by
9## the Free Software Foundation; either version 2 of the License, or
10## (at your option) any later version.
11##
12## This program is distributed in the hope that it will be of some
13## interest to somebody, but WITHOUT ANY WARRANTY; without even the
14## implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15## See the GNU General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with this program; see the file COPYING or COPYING.txt. If not,
19## write to the Free Software Foundation, Inc.,
20## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21## The license can also be found at the GNU/FSF website: http://www.gnu.org
22##
23## Stephen M. Gava
24## <elguavas@users.sourceforge.net>
25## http://pyching.sourgeforge.net
26##
27##---------------------------------------------------------------------------##
28"""
29a couple of classes for implementing partial tabbed-page like behaviour
30"""
31
32from Tkinter import *
33
34class PageTab(Frame):
35 """
36 a 'page tab' like framed button
37 """
38 def __init__(self,parent):
39 Frame.__init__(self, parent,borderwidth=2,relief=RIDGE)
40 self.button=Radiobutton(self,padx=5,pady=5,takefocus=FALSE,
41 underline=0,indicatoron=FALSE,highlightthickness=0,
42 borderwidth=0,selectcolor=self.cget('bg'))
43 self.button.pack()
44
45class TabPageSet(Frame):
46 """
47 a set of 'pages' with TabButtons for controlling their display
48 """
49 def __init__(self,parent,pageNames,**kw):
50 """
51 pageNames - a list of strings, each string will be the dictionary key
52 to a page's data, and the name displayed on the page's tab. Should be
53 specified in desired page order. The first page will be the default
54 and first active page.
55 """
56 Frame.__init__(self, parent, kw)
57 self.grid_location(0,0)
58 self.columnconfigure(0,weight=1)
59 self.rowconfigure(1,weight=1)
60 self.tabBar=Frame(self)
61 self.tabBar.grid(row=0,column=0,sticky=EW)
62 self.activePage=StringVar(self)
63 self.defaultPage=''
64 self.pages={}
65 for name in pageNames:
66 self.AddPage(name)
67
68 def ChangePage(self,pageName=None):
69 if pageName:
70 if pageName in self.pages.keys():
71 self.activePage.set(pageName)
72 else:
73 raise 'Invalid TabPage Name'
74 ## pop up the active 'tab' only
75 for page in self.pages.keys():
76 self.pages[page]['tab'].config(relief=RIDGE)
77 self.pages[self.GetActivePage()]['tab'].config(relief=RAISED)
78 ## switch page
79 self.pages[self.GetActivePage()]['page'].lift()
80
81 def GetActivePage(self):
82 return self.activePage.get()
83
84 def AddPage(self,pageName):
85 if pageName in self.pages.keys():
86 raise 'TabPage Name Already Exists'
87 self.pages[pageName]={'tab':PageTab(self.tabBar),
88 'page':Frame(self,borderwidth=2,relief=RAISED)}
89 self.pages[pageName]['tab'].button.config(text=pageName,
90 command=self.ChangePage,variable=self.activePage,
91 value=pageName)
92 self.pages[pageName]['tab'].pack(side=LEFT)
93 self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW)
94 if len(self.pages)==1: # adding first page
95 self.defaultPage=pageName
96 self.activePage.set(self.defaultPage)
97 self.ChangePage()
98
99 def RemovePage(self,pageName):
100 if not pageName in self.pages.keys():
101 raise 'Invalid TabPage Name'
102 self.pages[pageName]['tab'].pack_forget()
103 self.pages[pageName]['page'].grid_forget()
104 self.pages[pageName]['tab'].destroy()
105 self.pages[pageName]['page'].destroy()
106 del(self.pages[pageName])
107 # handle removing last remaining, or default, or active page
108 if not self.pages: # removed last remaining page
109 self.defaultPage=''
110 return
111 if pageName==self.defaultPage: # set a new default page
112 self.defaultPage=\
113 self.tabBar.winfo_children()[0].button.cget('text')
114 if pageName==self.GetActivePage(): # set a new active page
115 self.activePage.set(self.defaultPage)
116 self.ChangePage()
117
118if __name__ == '__main__':
119 #test the dialog
120 root=Tk()
121 tabPage=TabPageSet(root,pageNames=['Foobar','Baz'])
122 tabPage.pack(expand=TRUE,fill=BOTH)
123 Label(tabPage.pages['Foobar']['page'],text='Foo',pady=20).pack()
124 Label(tabPage.pages['Foobar']['page'],text='Bar',pady=20).pack()
125 Label(tabPage.pages['Baz']['page'],text='Baz').pack()
126 entryPgName=Entry(root)
127 buttonAdd=Button(root,text='Add Page',
128 command=lambda:tabPage.AddPage(entryPgName.get()))
129 buttonRemove=Button(root,text='Remove Page',
130 command=lambda:tabPage.RemovePage(entryPgName.get()))
131 labelPgName=Label(root,text='name of page to add/remove:')
132 buttonAdd.pack(padx=5,pady=5)
133 buttonRemove.pack(padx=5,pady=5)
134 labelPgName.pack(padx=5)
135 entryPgName.pack(padx=5)
136 root.mainloop()
137