• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""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.  Note that the
11      Viewer typically does *not* update itself before calling update_views(),
12      since this would cause it to get updated twice.
13
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
42"""
43
44import sys
45import marshal
46
47
48
49class Switchboard:
50    def __init__(self, initfile):
51        self.__initfile = initfile
52        self.__colordb = None
53        self.__optiondb = {}
54        self.__views = []
55        self.__red = 0
56        self.__green = 0
57        self.__blue = 0
58        self.__canceled = 0
59        # read the initialization file
60        fp = None
61        if initfile:
62            try:
63                try:
64                    fp = open(initfile, 'rb')
65                    self.__optiondb = marshal.load(fp)
66                    if not isinstance(self.__optiondb, dict):
67                        print('Problem reading options from file:', initfile,
68                              file=sys.stderr)
69                        self.__optiondb = {}
70                except (IOError, EOFError, ValueError):
71                    pass
72            finally:
73                if fp:
74                    fp.close()
75
76    def add_view(self, view):
77        self.__views.append(view)
78
79    def update_views(self, red, green, blue):
80        self.__red = red
81        self.__green = green
82        self.__blue = blue
83        for v in self.__views:
84            v.update_yourself(red, green, blue)
85
86    def update_views_current(self):
87        self.update_views(self.__red, self.__green, self.__blue)
88
89    def current_rgb(self):
90        return self.__red, self.__green, self.__blue
91
92    def colordb(self):
93        return self.__colordb
94
95    def set_colordb(self, colordb):
96        self.__colordb = colordb
97        for v in self.__views:
98            if hasattr(v, 'colordb_changed'):
99                v.colordb_changed(colordb)
100        self.update_views_current()
101
102    def optiondb(self):
103        return self.__optiondb
104
105    def save_views(self):
106        # 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:
111            if hasattr(v, 'save_options'):
112                v.save_options(self.__optiondb)
113        # 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()
116        fp = None
117        try:
118            try:
119                fp = open(self.__initfile, 'wb')
120            except IOError:
121                print('Cannot write options to file:', \
122                      self.__initfile, file=sys.stderr)
123            else:
124                marshal.dump(self.__optiondb, fp)
125        finally:
126            if fp:
127                fp.close()
128
129    def withdraw_views(self):
130        for v in self.__views:
131            if hasattr(v, 'withdraw'):
132                v.withdraw()
133
134    def canceled(self, flag=1):
135        self.__canceled = flag
136
137    def canceled_p(self):
138        return self.__canceled
139