source: trunk/tools/editor/scripts/editor.py @ 3513

Revision 3513, 15.2 KB checked in by helios2000, 8 years ago (diff)
  • Property svn:eol-style set to native
  • Property svn:mergeinfo set to (toggle deleted branches)
    /trunk/clients/editor/scripts/editor.py2779-2780
Line 
1# -*- coding: utf-8 -*-
2
3# ####################################################################
4#  Copyright (C) 2005-2010 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"""
25Editor
26======
27
28This class serves as
29"""
30
31import sys
32import os
33import traceback
34
35fife_path = os.path.join('..','..','engine','python')
36if os.path.isdir(fife_path) and fife_path not in sys.path:
37   sys.path.insert(0,fife_path)
38
39from fife import fife
40print "Using the FIFE python module found here: ", os.path.dirname(fife.__file__)
41
42from fife.extensions import loaders
43import events
44import plugin
45
46from fife.extensions.basicapplication import ApplicationBase
47
48from fife.extensions import pychan
49from fife.extensions.pychan.tools import callbackWithArguments as cbwa
50
51from events import *
52from gui import ToolBar, action
53from gui.action import Action, ActionGroup
54from gui.filemanager import FileManager
55from gui.mainwindow import MainWindow
56from gui.mapeditor import MapEditor
57from gui.menubar import Menu, MenuBar
58from gui.error import ErrorDialog
59from mapview import MapView
60from fife.extensions.fife_settings import Setting
61
62TDS = Setting(app_name="editor")
63
64def getEditor():
65   """ Returns the Global editor instance """
66   if Editor.editor is None:
67      Editor(None)
68   return Editor.editor
69
70class Editor(ApplicationBase, MainWindow):
71   """ Editor sets up all subsystems and provides access to them """
72   editor = None
73
74   def __init__(self, params, *args, **kwargs):
75      Editor.editor = self
76   
77      self._filemanager = None
78   
79      self._params = params
80      self._eventlistener = None
81      self._pluginmanager = None
82     
83      self._inited = False
84     
85      self._mapview = None
86      self._mapviewlist = []
87      self._mapgroup = None
88      self._mapbar = None
89      self._maparea = None
90      self._mapeditor = None
91     
92      self._file_menu = None
93      self._edit_menu = None
94      self._view_menu = None
95      self._tools_menu = None
96      self._help_menu = None
97     
98      self._change_map = -1
99     
100      self._settings = TDS
101
102      self._lighting_mode = int(TDS.get("FIFE", "Lighting"))     
103      self._help_dialog = None
104   
105      ApplicationBase.__init__(self, TDS, *args, **kwargs)
106      MainWindow.__init__(self, *args, **kwargs)
107     
108   def _initTools(self):
109      """ Initializes tools """
110      self._pluginmanager = plugin.PluginManager(self.getSettings())
111     
112      self._filemanager = FileManager()
113      self._toolbar.adaptLayout()
114      self._mapeditor = MapEditor()
115     
116   def _initGui(self):
117      """ Sets up the GUI """
118      screen_width = self.engine.getSettings().getScreenWidth()
119      screen_height = self.engine.getSettings().getScreenHeight()
120      MainWindow.initGui(self, screen_width, screen_height)
121
122      self._toolbox = ToolBar(title=u"", orientation=1)
123      self._toolbox.position_technique = "explicit"
124      self._toolbox.position = (150, 150)
125     
126      self._mapbar = ToolBar(name="MapBar", panel_size=20)
127      self._mapbar.setDocked(True)
128     
129      self._maparea = pychan.widgets.VBox()
130      self._maparea.opaque = False
131      self._maparea.is_focusable = True
132     
133      # Capture mouse and key events for EventListener
134      cw = self._maparea
135      cw.capture(self.__sendMouseEvent, "mouseEntered")
136      cw.capture(self.__sendMouseEvent, "mouseExited")
137      cw.capture(self.__sendMouseEvent, "mousePressed")
138      cw.capture(self.__sendMouseEvent, "mouseReleased")
139      cw.capture(self.__sendMouseEvent, "mouseClicked")
140      cw.capture(self.__sendMouseEvent, "mouseMoved")
141      cw.capture(self.__sendMouseEvent, "mouseWheelMovedUp")
142      cw.capture(self.__sendMouseEvent, "mouseWheelMovedDown")
143      cw.capture(self.__sendMouseEvent, "mouseDragged")
144      cw.capture(self.__sendKeyEvent, "keyPressed")
145      cw.capture(self.__sendKeyEvent, "keyReleased")
146     
147      self._centralwidget.addChild(self._mapbar)
148      self._centralwidget.addChild(self._maparea)
149     
150      self._initActions()
151     
152      self._toolbox.show()
153     
154      events.preMapClosed.connect(self._mapRemoved)
155
156   def _initActions(self):
157      """ Initializes toolbar and menubar buttons """
158      exitAction = Action(u"Exit", "gui/icons/quit.png")
159      exitAction.helptext = u"Exit program"
160      action.activated.connect(self.quit, sender=exitAction)
161     
162      self._file_menu = Menu(name=u"File")
163      self._file_menu.addAction(exitAction)
164     
165      self._edit_menu = Menu(name=u"Edit")
166      self._view_menu = Menu(name=u"View")
167      self._tools_menu = Menu(name=u"Tools")
168      self._window_menu = Menu(name=u"Window")
169      self._help_menu = Menu(name=u"Help")
170     
171      self._action_show_statusbar = Action(u"Statusbar")
172      self._action_show_statusbar.helptext = u"Toggle statusbar"
173      action.activated.connect(self.toggleStatusbar, sender=self._action_show_statusbar)
174     
175      self._action_show_toolbar = Action(u"Toolbar")
176      self._action_show_toolbar.helptext = u"Toggle toolbar"
177      action.activated.connect(self.toggleToolbar, sender=self._action_show_toolbar)
178     
179      self._action_show_toolbox = Action(u"Tool box")
180      self._action_show_toolbox.helptext = u"Toggle tool box"
181      action.activated.connect(self.toggleToolbox, sender=self._action_show_toolbox)
182     
183      self._view_menu.addAction(self._action_show_statusbar)
184      self._view_menu.addAction(self._action_show_toolbar)
185      self._view_menu.addAction(self._action_show_toolbox)
186      self._view_menu.addSeparator()
187   
188   
189      test_action1 = Action(u"Cycle buttonstyles", "gui/icons/cycle_styles.png")
190      test_action1.helptext = u"Cycles button styles. There are currently four button styles."
191      action.activated.connect(self._actionActivated, sender=test_action1)
192      self._view_menu.addAction(test_action1)
193
194      test_action2 = Action(u"Toggle Blocking")
195      test_action2.helptext = u"Toggles the blocking infos for the instances."
196      action.activated.connect(self.toggleBlocking, sender=test_action2)
197      self._view_menu.addAction(test_action2)
198
199      test_action3 = Action(u"Toggle Grid")
200      test_action3.helptext = u"Toggles the grids of the map."
201      action.activated.connect(self.toggleGrid, sender=test_action3)
202      self._view_menu.addAction(test_action3)
203
204      test_action4 = Action(u"Toggle Coordinates")
205      test_action4.helptext = u"Toggles the coordinates of the map."
206      action.activated.connect(self.toggleCoordinates, sender=test_action4)
207      self._view_menu.addAction(test_action4)     
208     
209      self._mapgroup = ActionGroup(exclusive=True, name="Mapgroup")
210      self._mapbar.addAction(self._mapgroup)
211      self._window_menu.addAction(self._mapgroup)
212     
213      help_action = Action(u"Help", "gui/icons/help.png")
214      help_action.helptext = u"Displays a window with some simple instructions"
215      action.activated.connect(self._showHelpDialog, sender=help_action)
216      self._help_menu.addAction(help_action)
217     
218      self._menubar.addMenu(self._file_menu)
219      self._menubar.addMenu(self._edit_menu)
220      self._menubar.addMenu(self._view_menu)
221      self._menubar.addMenu(self._tools_menu)
222      self._menubar.addMenu(self._window_menu)
223      self._menubar.addMenu(self._help_menu)
224   
225   def _actionActivated(self, sender):
226      self._toolbar.button_style += 1
227     
228   def _showHelpDialog(self, sender):
229      """ Shows the help dialog """
230      if self._help_dialog is not None:
231         self._help_dialog.show()
232         return
233     
234      self._help_dialog = pychan.loadXML("gui/help.xml")
235      self._help_dialog.findChild(name="closeButton").capture(self._help_dialog.hide)
236     
237      f = open('lang/infotext.txt', 'r')
238      self._help_dialog.findChild(name="helpText").text = unicode(f.read())
239      f.close()
240     
241      self._help_dialog.show()
242     
243   def toggleStatusbar(self):
244      """ Toggles status bar """
245      statusbar = self.getStatusBar()
246      if statusbar.max_size[1] > 0:
247         statusbar.min_size=(statusbar.min_size[0], 0)
248         statusbar.max_size=(statusbar.max_size[0], 0)
249         self._action_show_statusbar.setChecked(False)
250      else:
251         statusbar.min_size=(statusbar.min_size[0], statusbar.min_size[0])
252         statusbar.max_size=(statusbar.max_size[0], statusbar.max_size[0])
253         self._action_show_statusbar.setChecked(True)
254      statusbar.adaptLayout()
255         
256   def toggleToolbar(self):
257      """ Toggles toolbar """
258      toolbar = self.getToolBar()
259      if toolbar.isVisible():
260         toolbar.setDocked(False)
261         toolbar.hide()
262         self._action_show_toolbar.setChecked(False)
263      else: 
264         tx = toolbar.x
265         ty = toolbar.y
266         toolbar.show()
267         toolbar.x = tx
268         toolbar.y = ty
269         self._action_show_toolbar.setChecked(True)
270         
271   def toggleToolbox(self):
272      """ Toggles tool box """
273      toolbox = self.getToolbox()
274      if toolbox.isVisible():
275         toolbox.setDocked(False)
276         toolbox.hide()
277         self._action_show_toolbox.setChecked(False)
278      else:
279         tx = toolbox.x
280         ty = toolbox.y
281         toolbox.show()
282         toolbox.x = tx
283         toolbox.y = ty
284         self._action_show_toolbox.setChecked(True)
285      toolbox.adaptLayout()
286
287   def toggleBlocking(self, sender):
288      if self._mapview is not None:
289         for cam in self._mapview.getMap().getCameras():       
290            r = fife.BlockingInfoRenderer.getInstance(cam)
291            r.setEnabled(not r.isEnabled())
292
293   def toggleGrid(self, sender):
294      if self._mapview is not None:
295         for cam in self._mapview.getMap().getCameras():       
296            r = fife.GridRenderer.getInstance(cam)
297            r.setEnabled(not r.isEnabled())
298
299   def toggleCoordinates(self, sender):
300      if self._mapview is not None:
301         for cam in self._mapview.getMap().getCameras():
302            r = fife.CoordinateRenderer.getInstance(cam)
303            if not r.isEnabled():
304               r.clearActiveLayers()
305               color = str(self._settings.get("Colors", "Coordinate", "255,255,255"))
306               r.setColor(*[int(c) for c in color.split(',')])
307               for layer in self._mapview.getMap().getLayers():
308                  if layer.areInstancesVisible():
309                     r.addActiveLayer(layer)
310               r.setEnabled(True)
311            else:
312               r.setEnabled(False)
313
314   def getToolbox(self): 
315      return self._toolbox
316   
317   def getPluginManager(self): 
318      return self._pluginmanager
319     
320   def getEngine(self): 
321      return self.engine
322
323   def getMapViews(self):
324      return self._mapviewlist
325     
326   def getActiveMapView(self):
327      return self._mapview
328     
329   def getSettings(self):
330      return self._settings;
331
332   def getObject(self):
333      return self._mapeditor.getObject()
334
335   def showMapView(self, mapview):
336      """ Switches to mapview. """
337      if mapview is None or mapview == self._mapview:
338         return
339         
340      if self._mapview != None and mapview != self._mapview:
341         # need to disable the cameras from the previous map
342         # if it exists before switching
343         if self._mapview.getMap() != None:
344            for cam in self._mapview.getMap().getCameras():
345               cam.setEnabled(False)
346     
347      # if light model is set then enable LightRenderer for all layers
348      if self._lighting_mode is not 0:
349         for cam in mapview.getMap().getCameras():
350            renderer = fife.LightRenderer.getInstance(cam)
351            renderer.activateAllLayers(mapview.getMap())
352            renderer.setEnabled(not renderer.isEnabled())
353     
354      events.preMapShown.send(sender=self, mapview=mapview)
355      self._mapview = mapview
356      self._mapview.show()
357      events.postMapShown.send(sender=self, mapview=mapview)
358
359   def createListener(self):
360      """ Creates the event listener. This is called by ApplicationBase """
361      if self._eventlistener is None:
362         self._eventlistener = EventListener(self.engine)
363     
364      return self._eventlistener
365     
366   def getEventListener(self):
367      """ Returns the event listener """
368      return self._eventlistener
369   
370   def newMapView(self, map):
371      """ Creates a new map view """
372      mapview = MapView(map)
373     
374      self._mapviewlist.append(mapview)
375     
376      map_action = Action(unicode(map.getId()))
377      action.activated.connect(cbwa(self.showMapView, mapview), sender=map_action, weak=False)
378      self._mapgroup.addAction(map_action)
379     
380      self.showMapView(mapview)
381     
382      events.mapAdded.send(sender=self, map=map)
383     
384      return mapview
385     
386   def _mapRemoved(self, mapview):
387      index = self._mapviewlist.index(mapview)-1
388     
389      for cam in mapview.getMap().getCameras():
390         cam.setEnabled(False)
391         
392      self._mapviewlist.remove(mapview)
393     
394      # Remove tab
395      for map_action in self._mapgroup.getActions():
396         if map_action.text == unicode(mapview.getMap().getId()):
397            self._mapgroup.removeAction(map_action)
398            break
399           
400      # Change mapview
401      if len(self._mapviewlist) > 0:
402         if index < 0: 
403            index = 0
404         self._change_map = index
405      else:
406         self._mapview = None
407
408   def openFile(self, path):
409      """ Opens a file """
410      try:
411         if self._lighting_mode == 0:
412            map = loaders.loadMapFile(path, self.engine)
413         else:
414            map = loaders.loadMapFile(path, self.engine, extensions = {'lights': True})
415         return self.newMapView(map)
416      except:
417         traceback.print_exc(sys.exc_info()[1])
418         errormsg = u"Opening map failed:\n"
419         errormsg += u"File: "+unicode(path, sys.getfilesystemencoding())+u"\n"
420         errormsg += u"Error: "+unicode(sys.exc_info()[1])
421         ErrorDialog(errormsg)
422         return None
423   
424   def saveAll(self):
425      """ Saves all open maps """
426      tmpview = self._mapview
427      for mapview in self._mapviewlist:
428         self._mapview = mapview
429         self._filemanager.save()
430      self._mapview = tmpview
431     
432   def quit(self):
433      """ Quits the editor. An onQuit signal is sent before the application closes """
434      events.onQuit.send(sender=self)
435     
436      self._settings.saveSettings()
437      ApplicationBase.quit(self)
438
439   def _pump(self):
440      """ Called once per frame """
441      # ApplicationBase and Engine should be done initializing at this point
442      if self._inited == False:
443         self._initGui()
444         self._initTools()
445         if self._params: self.openFile(self._params)
446         self._inited = True
447         
448      # FIXME: This isn't very nice, but it is needed to change the map
449      #      outside the callback.
450      if self._change_map >= 0 and len(self._mapviewlist) > 0:
451         if self._change_map >= len(self._mapviewlist):
452            self._change_map = len(self._mapviewlist)-1
453         mapview = self._mapviewlist[self._change_map]
454         
455         self.showMapView(mapview)
456         self._change_map = -1
457     
458      events.onPump.send(sender=self)
459     
460   def __sendMouseEvent(self, event, **kwargs):
461      """ Function used to capture mouse events for EventListener """
462      ms_event = fife.MouseEvent
463      type = event.getType()
464     
465      if type == ms_event.MOVED:
466         mouseMoved.send(sender=self._maparea, event=event)
467         
468      elif type == ms_event.PRESSED:
469         mousePressed.send(sender=self._maparea, event=event)
470         
471      elif type == ms_event.RELEASED:
472         mouseReleased.send(sender=self._maparea, event=event)
473         
474      elif type == ms_event.WHEEL_MOVED_DOWN:
475         mouseWheelMovedDown.send(sender=self._maparea, event=event)
476         
477      elif type == ms_event.WHEEL_MOVED_UP:
478         mouseWheelMovedUp.send(sender=self._maparea, event=event)
479         
480      elif type == ms_event.CLICKED:
481         mouseClicked.send(sender=self._maparea, event=event)
482         
483      elif type == ms_event.ENTERED:
484         mouseEntered.send(sender=self._maparea, event=event)
485         
486      elif type == ms_event.EXITED:
487         mouseExited.send(sender=self._maparea, event=event)
488         
489      elif type == ms_event.DRAGGED:
490         mouseDragged.send(sender=self._maparea, event=event)
491     
492   def __sendKeyEvent(self, event, **kwargs):
493      """ Function used to capture key events for EventListener """
494      type = event.getType()
495     
496      if type == fife.KeyEvent.PRESSED:
497         keyPressed.send(sender=self._maparea, event=event)
498     
499      elif type == fife.KeyEvent.RELEASED:
500         keyReleased.send(sender=self._maparea, event=event)
501         
502     
503
504     
Note: See TracBrowser for help on using the repository browser.