comparison tools/editor/scripts/editor.py @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children ac7806c46b94
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
1 # -*- coding: utf-8 -*-
2
3 # ####################################################################
4 # Copyright (C) 2005-2009 by the FIFE team
5 # http://www.fifengine.de
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 Editor
26 ======
27
28 This class serves as
29 """
30
31 import sys
32 import traceback
33
34 from fife import fife
35 from fife.extensions import loaders
36 import events
37 import plugin
38
39 from fife.extensions.basicapplication import ApplicationBase
40
41 from fife.extensions import pychan
42 from fife.extensions.pychan.tools import callbackWithArguments as cbwa
43
44 from events import *
45 from gui import ToolBar, action
46 from gui.action import Action, ActionGroup
47 from gui.filemanager import FileManager
48 from gui.mainwindow import MainWindow
49 from gui.mapeditor import MapEditor
50 from gui.menubar import Menu, MenuBar
51 from gui.error import ErrorDialog
52 from mapview import MapView
53 from settings import Settings
54
55 def getEditor():
56 """ Returns the Global editor instance """
57 if Editor.editor is None:
58 Editor(None)
59 return Editor.editor
60
61 class Editor(ApplicationBase, MainWindow):
62 """ Editor sets up all subsystems and provides access to them """
63 editor = None
64
65 def __init__(self, params, *args, **kwargs):
66 Editor.editor = self
67
68 self._filemanager = None
69
70 self._params = params
71 self._eventlistener = None
72 self._pluginmanager = None
73
74 self._inited = False
75
76 self._mapview = None
77 self._mapviewlist = []
78 self._mapgroup = None
79 self._mapbar = None
80 self._maparea = None
81 self._mapeditor = None
82
83 self._file_menu = None
84 self._edit_menu = None
85 self._view_menu = None
86 self._tools_menu = None
87 self._help_menu = None
88
89 self._settings = None
90
91 self._help_dialog = None
92
93 ApplicationBase.__init__(self, *args, **kwargs)
94 MainWindow.__init__(self, *args, **kwargs)
95 pychan.init(self.engine, debug=False)
96
97
98 def loadSettings(self):
99 """
100 Load the settings from a python file and load them into the engine.
101 Called in the ApplicationBase constructor.
102 """
103 self._settings = Settings()
104 TDS = self._settings
105
106 glyphDft = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`'*#=[]\\\""
107 engineSetting = self.engine.getSettings()
108 engineSetting.setDefaultFontGlyphs(TDS.get("FIFE", "FontGlyphs", glyphDft))
109 engineSetting.setDefaultFontPath(TDS.get("FIFE", "Font", "fonts/FreeSans.ttf"))
110 engineSetting.setDefaultFontSize(12)
111 engineSetting.setBitsPerPixel(TDS.get("FIFE", "BitsPerPixel", 0))
112 engineSetting.setInitialVolume(TDS.get("FIFE", "InitialVolume", 5.0))
113 engineSetting.setSDLRemoveFakeAlpha(TDS.get("FIFE", "SDLRemoveFakeAlpha", 1))
114 engineSetting.setScreenWidth(TDS.get("FIFE", "ScreenWidth", 1024))
115 engineSetting.setScreenHeight(TDS.get("FIFE", "ScreenHeight", 768))
116 engineSetting.setRenderBackend(TDS.get("FIFE", "RenderBackend", "OpenGL"))
117 engineSetting.setFullScreen(TDS.get("FIFE", "FullScreen", 0))
118
119 engineSetting.setWindowTitle(TDS.get("FIFE", "WindowTitle", "No window title set"))
120 engineSetting.setWindowIcon(TDS.get("FIFE", "WindowIcon", ""))
121 engineSetting.setImageChunkingSize(TDS.get("FIFE", "ImageChunkSize", 256))
122
123 def initLogging(self):
124 """
125 Initialize the LogManager.
126 """
127 from fife.extensions import fifelog
128
129 logModules = self._settings.get("FIFE", "LogModules")
130 self.log = fifelog.LogManager(self.engine, self._settings.get("FIFE", "LogToPrompt"), self._settings.get("FIFE", "LogToFile"))
131 if logModules:
132 self.log.setVisibleModules(*logModules)
133
134 def _initTools(self):
135 """ Initializes tools """
136 self._pluginmanager = plugin.PluginManager(self.getSettings())
137
138 self._filemanager = FileManager()
139 self._toolbar.adaptLayout()
140 self._mapeditor = MapEditor()
141
142 def _initGui(self):
143 """ Sets up the GUI """
144 screen_width = self.engine.getSettings().getScreenWidth()
145 screen_height = self.engine.getSettings().getScreenHeight()
146 MainWindow.initGui(self, screen_width, screen_height)
147
148 self._toolbox = ToolBar(title=u"", orientation=1)
149 self._toolbox.position_technique = "explicit"
150 self._toolbox.position = (150, 150)
151
152 self._mapbar = ToolBar(name="MapBar", panel_size=20)
153 self._mapbar.setDocked(True)
154
155 self._maparea = pychan.widgets.VBox()
156 self._maparea.opaque = False
157 self._maparea.is_focusable = True
158
159 # Capture mouse and key events for EventListener
160 cw = self._maparea
161 cw.capture(self.__sendMouseEvent, "mouseEntered")
162 cw.capture(self.__sendMouseEvent, "mouseExited")
163 cw.capture(self.__sendMouseEvent, "mousePressed")
164 cw.capture(self.__sendMouseEvent, "mouseReleased")
165 cw.capture(self.__sendMouseEvent, "mouseClicked")
166 cw.capture(self.__sendMouseEvent, "mouseMoved")
167 cw.capture(self.__sendMouseEvent, "mouseWheelMovedUp")
168 cw.capture(self.__sendMouseEvent, "mouseWheelMovedDown")
169 cw.capture(self.__sendMouseEvent, "mouseDragged")
170 cw.capture(self.__sendKeyEvent, "keyPressed")
171 cw.capture(self.__sendKeyEvent, "keyReleased")
172
173 self._centralwidget.addChild(self._mapbar)
174 self._centralwidget.addChild(self._maparea)
175
176 self._initActions()
177
178 self._toolbox.show()
179
180 def _initActions(self):
181 """ Initializes toolbar and menubar buttons """
182 exitAction = Action(u"Exit", "gui/icons/quit.png")
183 exitAction.helptext = u"Exit program"
184 action.activated.connect(self.quit, sender=exitAction)
185
186 self._file_menu = Menu(name=u"File")
187 self._file_menu.addAction(exitAction)
188
189 self._edit_menu = Menu(name=u"Edit")
190 self._view_menu = Menu(name=u"View")
191 self._tools_menu = Menu(name=u"Tools")
192 self._window_menu = Menu(name=u"Window")
193 self._help_menu = Menu(name=u"Help")
194
195 self._action_show_statusbar = Action(u"Statusbar")
196 self._action_show_statusbar.helptext = u"Toggle statusbar"
197 action.activated.connect(self.toggleStatusbar, sender=self._action_show_statusbar)
198
199 self._action_show_toolbar = Action(u"Toolbar")
200 self._action_show_toolbar.helptext = u"Toggle toolbar"
201 action.activated.connect(self.toggleToolbar, sender=self._action_show_toolbar)
202
203 self._action_show_toolbox = Action(u"Tool box")
204 self._action_show_toolbox.helptext = u"Toggle tool box"
205 action.activated.connect(self.toggleToolbox, sender=self._action_show_toolbox)
206
207 self._view_menu.addAction(self._action_show_statusbar)
208 self._view_menu.addAction(self._action_show_toolbar)
209 self._view_menu.addAction(self._action_show_toolbox)
210 self._view_menu.addSeparator()
211
212
213 test_action1 = Action(u"Cycle buttonstyles", "gui/icons/cycle_styles.png")
214 test_action1.helptext = u"Cycles button styles. There are currently four button styles."
215 action.activated.connect(self._actionActivated, sender=test_action1)
216 self._view_menu.addAction(test_action1)
217
218 self._mapgroup = ActionGroup(exclusive=True, name="Mapgroup")
219 self._mapbar.addAction(self._mapgroup)
220 self._window_menu.addAction(self._mapgroup)
221
222 help_action = Action(u"Help", "gui/icons/help.png")
223 help_action.helptext = u"Displays a window with some simple instructions"
224 action.activated.connect(self._showHelpDialog, sender=help_action)
225 self._help_menu.addAction(help_action)
226
227 self._menubar.addMenu(self._file_menu)
228 self._menubar.addMenu(self._edit_menu)
229 self._menubar.addMenu(self._view_menu)
230 self._menubar.addMenu(self._tools_menu)
231 self._menubar.addMenu(self._window_menu)
232 self._menubar.addMenu(self._help_menu)
233
234 def _actionActivated(self, sender):
235 self._toolbar.button_style += 1
236
237 def _showHelpDialog(self, sender):
238 """ Shows the help dialog """
239 if self._help_dialog is not None:
240 self._help_dialog.show()
241 return
242
243 self._help_dialog = pychan.loadXML("gui/help.xml")
244 self._help_dialog.findChild(name="closeButton").capture(self._help_dialog.hide)
245
246 f = open('lang/infotext.txt', 'r')
247 self._help_dialog.findChild(name="helpText").text = unicode(f.read())
248 f.close()
249
250 self._help_dialog.show()
251
252 def toggleStatusbar(self):
253 """ Toggles status bar """
254 statusbar = self.getStatusBar()
255 if statusbar.max_size[1] > 0:
256 statusbar.min_size=(statusbar.min_size[0], 0)
257 statusbar.max_size=(statusbar.max_size[0], 0)
258 self._action_show_statusbar.setChecked(False)
259 else:
260 statusbar.min_size=(statusbar.min_size[0], statusbar.min_size[0])
261 statusbar.max_size=(statusbar.max_size[0], statusbar.max_size[0])
262 self._action_show_statusbar.setChecked(True)
263 statusbar.adaptLayout()
264
265 def toggleToolbar(self):
266 """ Toggles toolbar """
267 toolbar = self.getToolBar()
268 if toolbar.isVisible():
269 toolbar.setDocked(False)
270 toolbar.hide()
271 self._action_show_toolbar.setChecked(False)
272 else:
273 tx = toolbar.x
274 ty = toolbar.y
275 toolbar.show()
276 toolbar.x = tx
277 toolbar.y = ty
278 self._action_show_toolbar.setChecked(True)
279
280 def toggleToolbox(self):
281 """ Toggles tool box """
282 toolbox = self.getToolbox()
283 if toolbox.isVisible():
284 toolbox.setDocked(False)
285 toolbox.hide()
286 self._action_show_toolbox.setChecked(False)
287 else:
288 tx = toolbox.x
289 ty = toolbox.y
290 toolbox.show()
291 toolbox.x = tx
292 toolbox.y = ty
293 self._action_show_toolbox.setChecked(True)
294 toolbox.adaptLayout()
295
296 def getToolbox(self):
297 return self._toolbox
298
299 def getPluginManager(self):
300 return self._pluginmanager
301
302 def getEngine(self):
303 return self.engine
304
305 def getMapViews(self):
306 return self._mapviewlist
307
308 def getActiveMapView(self):
309 return self._mapview
310
311 def getSettings(self):
312 return self._settings;
313
314 def showMapView(self, mapview):
315 """ Switches to mapview. """
316 if mapview is None or mapview == self._mapview:
317 return
318
319 events.preMapShown.send(sender=self, mapview=mapview)
320 self._mapview = mapview
321 self._mapview.show()
322 events.postMapShown.send(sender=self, mapview=mapview)
323
324 def createListener(self):
325 """ Creates the event listener. This is called by ApplicationBase """
326 if self._eventlistener is None:
327 self._eventlistener = EventListener(self.engine)
328
329 return self._eventlistener
330
331 def getEventListener(self):
332 """ Returns the event listener """
333 return self._eventlistener
334
335 def newMapView(self, map):
336 """ Creates a new map view """
337 mapview = MapView(map)
338
339 self._mapviewlist.append(mapview)
340
341 map_action = Action(unicode(map.getId()))
342 action.activated.connect(cbwa(self.showMapView, mapview), sender=map_action, weak=False)
343 self._mapgroup.addAction(map_action)
344
345 self.showMapView(mapview)
346
347 events.preMapClosed.connect(self._mapRemoved)
348 events.mapAdded.send(sender=self, map=map)
349
350 return mapview
351
352 def _mapRemoved(self, mapview):
353 events.preMapClosed.disconnect(self._mapRemoved)
354
355 index = self._mapviewlist.index(mapview)-1
356 self._mapviewlist.remove(mapview)
357
358 # Remove tab
359 for map_action in self._mapgroup.getActions():
360 if map_action.text == unicode(mapview.getMap().getId()):
361 self._mapgroup.removeAction(map_action)
362 break
363
364 # Change mapview
365 if index >= 0:
366 self.showMapView(self._mapviewlist[index])
367 else:
368 self._mapview = None
369 self.getEngine().getView().clearCameras()
370
371 def openFile(self, path):
372 """ Opens a file """
373 try:
374 map = loaders.loadMapFile(path, self.engine)
375 return self.newMapView(map)
376 except:
377 traceback.print_exc(sys.exc_info()[1])
378 errormsg = u"Opening map failed:\n"
379 errormsg += u"File: "+unicode(path, sys.getfilesystemencoding())+u"\n"
380 errormsg += u"Error: "+unicode(sys.exc_info()[1])
381 ErrorDialog(errormsg)
382 return None
383
384 def saveAll(self):
385 """ Saves all open maps """
386 tmpview = self._mapview
387 for mapview in self._mapviewlist:
388 self._mapview = mapview
389 self._filemanager.save()
390 self._mapview = tmpview
391
392 def quit(self):
393 """ Quits the editor. An onQuit signal is sent before the application closes """
394 events.onQuit.send(sender=self)
395
396 self._settings.saveSettings()
397 ApplicationBase.quit(self)
398
399 def _pump(self):
400 """ Called once per frame """
401 # ApplicationBase and Engine should be done initializing at this point
402 if self._inited == False:
403 self._initGui()
404 self._initTools()
405 if self._params: self.openFile(self._params)
406 self._inited = True
407
408 events.onPump.send(sender=self)
409
410 def __sendMouseEvent(self, event, **kwargs):
411 """ Function used to capture mouse events for EventListener """
412 ms_event = fife.MouseEvent
413 type = event.getType()
414
415 if type == ms_event.MOVED:
416 mouseMoved.send(sender=self._maparea, event=event)
417
418 elif type == ms_event.PRESSED:
419 mousePressed.send(sender=self._maparea, event=event)
420
421 elif type == ms_event.RELEASED:
422 mouseReleased.send(sender=self._maparea, event=event)
423
424 elif type == ms_event.WHEEL_MOVED_DOWN:
425 mouseWheelMovedDown.send(sender=self._maparea, event=event)
426
427 elif type == ms_event.WHEEL_MOVED_UP:
428 mouseWheelMovedUp.send(sender=self._maparea, event=event)
429
430 elif type == ms_event.CLICKED:
431 mouseClicked.send(sender=self._maparea, event=event)
432
433 elif type == ms_event.ENTERED:
434 mouseEntered.send(sender=self._maparea, event=event)
435
436 elif type == ms_event.EXITED:
437 mouseExited.send(sender=self._maparea, event=event)
438
439 elif type == ms_event.DRAGGED:
440 mouseDragged.send(sender=self._maparea, event=event)
441
442 def __sendKeyEvent(self, event, **kwargs):
443 """ Function used to capture key events for EventListener """
444 type = event.getType()
445
446 if type == fife.KeyEvent.PRESSED:
447 keyPressed.send(sender=self._maparea, event=event)
448
449 elif type == fife.KeyEvent.RELEASED:
450 keyReleased.send(sender=self._maparea, event=event)
451
452
453
454