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

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