Mercurial > fife-parpg
comparison engine/python/fife/extensions/fife_settings.py @ 497:559a26347730
Forgot to add fife_settings.py in my last commit. Adding it now.
author | prock@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Wed, 12 May 2010 22:03:32 +0000 |
parents | |
children | 3dff106b945b |
comparison
equal
deleted
inserted
replaced
496:987307d12235 | 497:559a26347730 |
---|---|
1 # -*- coding: utf-8 -*- | |
2 | |
3 # #################################################################### | |
4 # Copyright (C) 2005-2010 by the FIFE team | |
5 # http://www.fifengine.net | |
6 # This file is part of FIFE. | |
7 # | |
8 # FIFE is free software; you can redistribute it and/or | |
9 # modify it under the terms of the GNU Lesser General Public | |
10 # License as published by the Free Software Foundation; either | |
11 # version 2.1 of the License, or (at your option) any later version. | |
12 # | |
13 # This library is distributed in the hope that it will be useful, | |
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 # Lesser General Public License for more details. | |
17 # | |
18 # You should have received a copy of the GNU Lesser General Public | |
19 # License along with this library; if not, write to the | |
20 # Free Software Foundation, Inc., | |
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 # #################################################################### | |
23 | |
24 """ | |
25 Settings | |
26 ================================== | |
27 | |
28 This module provides a nice framework for loading and saving game settings. | |
29 It is by no means complete but it does provide a good starting point. | |
30 | |
31 @note: Please note that you MUST provide a default settings-dist.xml file | |
32 in the root directory of your project for this module to function correctly. | |
33 """ | |
34 | |
35 import shutil | |
36 import os | |
37 from StringIO import StringIO | |
38 | |
39 from fife.extensions import pychan | |
40 from fife.extensions.fife_utils import getUserDataDirectory | |
41 try: | |
42 import xml.etree.cElementTree as ET | |
43 except: | |
44 import xml.etree.ElementTree as ET | |
45 | |
46 | |
47 SETTINGS_GUI_XML="""\ | |
48 <Window name="Settings" title="Settings"> | |
49 <Label text="Settings menu!" /> | |
50 <HBox> | |
51 <VBox> | |
52 <Label text="Resolution:" /> | |
53 <Label text="Renderer:" /> | |
54 </VBox> | |
55 <VBox min_size="120,60"> | |
56 <DropDown name="screen_resolution" min_size="120,0" /> | |
57 <DropDown name="render_backend" min_size="120,0" /> | |
58 </VBox> | |
59 </HBox> | |
60 <CheckBox name="enable_fullscreen" text="Use the full screen mode" /> | |
61 <CheckBox name="enable_sound" text="Enable sound" /> | |
62 <HBox> | |
63 <Spacer /> | |
64 <Button name="cancelButton" text="Cancel" /> | |
65 <Button name="okButton" text="Ok" /> | |
66 <Button name="defaultButton" text="Defaults" /> | |
67 </HBox> | |
68 </Window> | |
69 """ | |
70 | |
71 CHANGES_REQUIRE_RESTART="""\ | |
72 <Window title="Changes require restart"> | |
73 <Label text="Some of your changes require you to restart." /> | |
74 <HBox> | |
75 <Spacer /> | |
76 <Button name="closeButton" text="Ok" /> | |
77 </HBox> | |
78 </Window> | |
79 """ | |
80 | |
81 class Setting(object): | |
82 """ | |
83 This class manages loading and saving of game settings. | |
84 | |
85 Usage:: | |
86 from fife.extensions.fife_settings import Setting | |
87 settings = Setting(app_name="myapp") | |
88 screen_width = settings.readSetting("ScreenWidth") | |
89 """ | |
90 def __init__(self, app_name="", settings_file="", settings_gui_xml=""): | |
91 """ | |
92 Initializes the Setting object. | |
93 | |
94 @param app_name: The applications name. If this parameter is provided | |
95 alone it will try to read the settings file from the users home directory. | |
96 In windows this will be something like: C:\Documents and Settings\user\Application Data\fife | |
97 @type app_name: C{string} | |
98 @param settings_file: The name of the settings file. If this parameter is | |
99 provided it will look for the setting file as you specify it, first looking | |
100 in the working directory. | |
101 @type settings_file: C{string} | |
102 @param settings_gui_xml: If you specify this parameter you can customize the look | |
103 of the settings dialog box. | |
104 @note: As of now you MUST have all the elements of the default settings dialog box. | |
105 At some point we may make it customizable. | |
106 | |
107 """ | |
108 self._app_name = app_name | |
109 self._settings_file = settings_file | |
110 self._settings_gui_xml = settings_gui_xml | |
111 | |
112 if self._settings_file == "": | |
113 self._settings_file = "settings.xml" | |
114 self._appdata = getUserDataDirectory("fife", self._app_name) | |
115 else: | |
116 self._appdata = os.path.dirname(self._settings_file) | |
117 self._settings_file = os.path.basename(self._settings_file) | |
118 | |
119 | |
120 if self._settings_gui_xml == "": | |
121 self.settings_gui_xml = SETTINGS_GUI_XML | |
122 | |
123 | |
124 if not os.path.exists(os.path.join(self._appdata, self._settings_file)): | |
125 shutil.copyfile('settings-dist.xml', os.path.join(self._appdata, self._settings_file)) | |
126 | |
127 | |
128 def onOptionsPress(self): | |
129 """ | |
130 Opends the options dialog box. Usually you would bind this to a button. | |
131 """ | |
132 self.changesRequireRestart = False | |
133 self.isSetToDefault = False | |
134 self.Resolutions = ['640x480', '800x600', '1024x768', '1280x800', '1440x900'] | |
135 if not hasattr(self, 'OptionsDlg'): | |
136 self.OptionsDlg = None | |
137 if not self.OptionsDlg: | |
138 self.OptionsDlg = pychan.loadXML(StringIO(SETTINGS_GUI_XML)) | |
139 self.OptionsDlg.distributeInitialData({ | |
140 'screen_resolution' : self.Resolutions, | |
141 'render_backend' : ['OpenGL', 'SDL'] | |
142 }) | |
143 self.OptionsDlg.distributeData({ | |
144 'screen_resolution' : self.Resolutions.index(str(self.readSetting("ScreenWidth")) + 'x' + str(self.readSetting("ScreenHeight"))), | |
145 'render_backend' : 0 if str(self.readSetting("RenderBackend")) == "OpenGL" else 1, | |
146 'enable_fullscreen' : int(self.readSetting("FullScreen")), | |
147 'enable_sound' : int(self.readSetting("PlaySounds")) | |
148 }) | |
149 self.OptionsDlg.mapEvents({ | |
150 'okButton' : self.saveSettings, | |
151 'cancelButton' : self.OptionsDlg.hide, | |
152 'defaultButton' : self.setDefaults | |
153 }) | |
154 self.OptionsDlg.show() | |
155 | |
156 def setDefaults(self): | |
157 """ | |
158 Overwrites the setting file with the default settings-dist.xml file. | |
159 """ | |
160 shutil.copyfile('settings-dist.xml', os.path.join(self._appdata, self._settings_file)) | |
161 self.isSetToDefault = True | |
162 self.changesRequireRestart = True | |
163 | |
164 def readSetting(self, name, type='int', strip=True, text=False): | |
165 if not hasattr(self, 'tree'): | |
166 self.tree = ET.parse(os.path.join(self._appdata, self._settings_file)) | |
167 self.root_element = self.tree.getroot() | |
168 element = self.root_element.find(name) | |
169 if element is not None: | |
170 element_value = element.text | |
171 if element_value is None: | |
172 if type == 'int': | |
173 return 0 | |
174 elif type == 'list': | |
175 list = [] | |
176 return list | |
177 else: | |
178 if type == 'int': | |
179 return element_value.strip() if strip else element_value | |
180 elif type == 'list': | |
181 list = [] | |
182 list_s = [] | |
183 list = str(element_value.strip()).split(";") | |
184 for item in list: | |
185 item = item.strip() | |
186 if text: | |
187 item = item.replace('\\n', '\n') | |
188 list_s.append(item) | |
189 return list_s | |
190 elif type == 'bool': | |
191 return False if element_value.strip() == 'False' else True | |
192 else: | |
193 print 'Setting,', name, 'does not exist!' | |
194 | |
195 def setSetting(self, name, value): | |
196 element = self.root_element.find(name) | |
197 if element is not None: | |
198 if value is not element.text: | |
199 element.text = str(value) | |
200 else: | |
201 print 'Setting,', name, 'does not exist!' | |
202 | |
203 def saveSettings(self): | |
204 """ | |
205 Writes the settings file. If a change requires a restart of the engine | |
206 it notifies you with a small dialog box. | |
207 """ | |
208 screen_resolution, render_backend, enable_fullscreen, enable_sound = self.OptionsDlg.collectData('screen_resolution', 'render_backend', 'enable_fullscreen', 'enable_sound') | |
209 render_backend = 'OpenGL' if render_backend is 0 else 'SDL' | |
210 if render_backend != str(self.readSetting("RenderBackend")): | |
211 self.setSetting('RenderBackend', render_backend) | |
212 self.changesRequireRestart = True | |
213 if int(enable_fullscreen) != int(self.readSetting("FullScreen")): | |
214 self.setSetting('FullScreen', int(enable_fullscreen)) | |
215 self.changesRequireRestart = True | |
216 if int(enable_sound) != int(self.readSetting("PlaySounds")): | |
217 self.setSetting('PlaySounds', int(enable_sound)) | |
218 self.changesRequireRestart = True | |
219 if screen_resolution != self.Resolutions.index(str(self.readSetting("ScreenWidth")) + 'x' + str(self.readSetting("ScreenHeight"))): | |
220 self.setSetting('ScreenWidth', int(self.Resolutions[screen_resolution].partition('x')[0])) | |
221 self.setSetting('ScreenHeight', int(self.Resolutions[screen_resolution].partition('x')[2])) | |
222 self.changesRequireRestart = True | |
223 | |
224 if not self.isSetToDefault: | |
225 self.tree.write(os.path.join(self._appdata, self._settings_file)) | |
226 self.OptionsDlg.hide() | |
227 if self.changesRequireRestart: | |
228 RestartDlg = pychan.loadXML(StringIO(CHANGES_REQUIRE_RESTART)) | |
229 RestartDlg.mapEvents({ 'closeButton' : RestartDlg.hide }) | |
230 RestartDlg.show() |