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()