blob: f67a1a951d34194fd6afbf67909405ca40c94af9 [file] [log] [blame]
Barry Warsaw4638c5b1998-10-02 16:20:14 +00001"""Switchboard class.
2
3This class is used to coordinate updates among all Viewers. Every Viewer must
4conform to the following interface:
5
6 - it must include a method called update_yourself() which takes three
7 arguments; the red, green, and blue values of the selected color.
8
9 - When a Viewer selects a color and wishes to update all other Views, it
10 should call update_views() on the Switchboard object. Not that the
11 Viewer typically does *not* update itself before calling update_views(),
12 since this would cause it to get updated twice.
Barry Warsaw2095b2f1999-04-27 18:53:29 +000013
14Optionally, Viewers can also implement:
15
16 - save_options() which takes an optiondb (a dictionary). Store into this
17 dictionary any values the Viewer wants to save in the persistent
18 ~/.pynche file. This dictionary is saved using marshal. The namespace
19 for the keys is ad-hoc; make sure you don't clobber some other Viewer's
20 keys!
21
22 - withdraw() which takes no arguments. This is called when Pynche is
23 unmapped. All Viewers should implement this.
24
25 - colordb_changed() which takes a single argument, an instance of
26 ColorDB. This is called whenever the color name database is changed and
27 gives a chance for the Viewers to do something on those events. See
28 ListViewer for details.
29
30External Viewers are found dynamically. Viewer modules should have names such
31as FooViewer.py. If such a named module has a module global variable called
32ADDTOVIEW and this variable is true, the Viewer will be added dynamically to
33the `View' menu. ADDTOVIEW contains a string which is used as the menu item
34to display the Viewer (one kludge: if the string contains a `%', this is used
35to indicate that the next character will get an underline in the menu,
36otherwise the first character is underlined).
37
38FooViewer.py should contain a class called FooViewer, and its constructor
39should take two arguments, an instance of Switchboard, and optionally a Tk
40master window.
41
Barry Warsaw4638c5b1998-10-02 16:20:14 +000042"""
43
Barry Warsaw4ab5ae21998-10-22 18:48:01 +000044import sys
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000045from types import DictType
46import marshal
47
Barry Warsaw987fb921998-09-28 15:59:21 +000048class Switchboard:
Barry Warsaw0604d721999-04-26 23:17:16 +000049 def __init__(self, initfile):
Barry Warsawca07ba01998-10-22 03:25:59 +000050 self.__initfile = initfile
Barry Warsaw0604d721999-04-26 23:17:16 +000051 self.__colordb = None
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000052 self.__optiondb = {}
53 self.__views = []
Barry Warsawa7ba45b1998-10-01 16:46:43 +000054 self.__red = 0
55 self.__green = 0
56 self.__blue = 0
Barry Warsawca07ba01998-10-22 03:25:59 +000057 self.__canceled = 0
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000058 # read the initialization file
59 fp = None
60 if initfile:
61 try:
62 try:
63 fp = open(initfile)
64 self.__optiondb = marshal.load(fp)
65 if type(self.__optiondb) <> DictType:
Barry Warsaw4ab5ae21998-10-22 18:48:01 +000066 sys.stderr.write(
67 'Problem reading options from file: %s\n' %
68 initfile)
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000069 self.__optiondb = {}
70 except (IOError, EOFError):
71 pass
72 finally:
73 if fp:
74 fp.close()
Barry Warsaw987fb921998-09-28 15:59:21 +000075
76 def add_view(self, view):
77 self.__views.append(view)
78
Barry Warsaw1ac18cd1998-09-28 23:41:12 +000079 def update_views(self, red, green, blue):
Barry Warsawa7ba45b1998-10-01 16:46:43 +000080 self.__red = red
81 self.__green = green
82 self.__blue = blue
Barry Warsaw987fb921998-09-28 15:59:21 +000083 for v in self.__views:
Barry Warsaw1ac18cd1998-09-28 23:41:12 +000084 v.update_yourself(red, green, blue)
Barry Warsawfda3ace1998-09-29 20:04:19 +000085
Barry Warsawa7ba45b1998-10-01 16:46:43 +000086 def update_views_current(self):
87 self.update_views(self.__red, self.__green, self.__blue)
88
Barry Warsawcd098671998-10-05 21:14:12 +000089 def current_rgb(self):
90 return self.__red, self.__green, self.__blue
91
Barry Warsawfda3ace1998-09-29 20:04:19 +000092 def colordb(self):
93 return self.__colordb
Barry Warsaw8a09e1c1998-10-20 20:45:46 +000094
Barry Warsaw0604d721999-04-26 23:17:16 +000095 def set_colordb(self, colordb):
96 self.__colordb = colordb
Barry Warsaw2095b2f1999-04-27 18:53:29 +000097 for v in self.__views:
98 if hasattr(v, 'colordb_changed'):
99 v.colordb_changed(colordb)
100 self.update_views_current()
Barry Warsaw0604d721999-04-26 23:17:16 +0000101
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000102 def optiondb(self):
103 return self.__optiondb
104
Barry Warsawca07ba01998-10-22 03:25:59 +0000105 def save_views(self):
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000106 # save the current color
107 self.__optiondb['RED'] = self.__red
108 self.__optiondb['GREEN'] = self.__green
109 self.__optiondb['BLUE'] = self.__blue
110 for v in self.__views:
Barry Warsawca07ba01998-10-22 03:25:59 +0000111 if hasattr(v, 'save_options'):
112 v.save_options(self.__optiondb)
Barry Warsaw0604d721999-04-26 23:17:16 +0000113 # save the name of the file used for the color database. we'll try to
114 # load this first.
115 self.__optiondb['DBFILE'] = self.__colordb.filename()
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000116 fp = None
117 try:
118 try:
Barry Warsawca07ba01998-10-22 03:25:59 +0000119 fp = open(self.__initfile, 'w')
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000120 except IOError:
Barry Warsaw4ab5ae21998-10-22 18:48:01 +0000121 sys.stderr.write('Cannot write options to file: %s\n' %
122 self.__initfile)
Barry Warsaw8a09e1c1998-10-20 20:45:46 +0000123 else:
124 marshal.dump(self.__optiondb, fp)
125 finally:
126 if fp:
127 fp.close()
Barry Warsawca07ba01998-10-22 03:25:59 +0000128
129 def withdraw_views(self):
130 for v in self.__views:
131 if hasattr(v, 'withdraw'):
132 v.withdraw()
133
Barry Warsaw4ab5ae21998-10-22 18:48:01 +0000134 def canceled(self, flag=1):
135 self.__canceled = flag
Barry Warsawca07ba01998-10-22 03:25:59 +0000136
137 def canceled_p(self):
138 return self.__canceled