comparison clients/editor/plugins/LayerTool.py @ 255:51cc05d862f2

Merged editor_rewrite branch to trunk. This contains changes that may break compatibility against existing clients. For a list of changes that may affect your client, see: http://wiki.fifengine.de/Changes_to_pychan_and_FIFE_in_editor_rewrite_branch
author cheesesucker@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 08 Jun 2009 16:00:02 +0000
parents
children 07709bffab8f
comparison
equal deleted inserted replaced
254:10b5f7f36dd4 255:51cc05d862f2
1 #!/usr/bin/env python
2 # coding: utf-8
3 # ###################################################
4 # Copyright (C) 2008 The Zero-Projekt team
5 # http://zero-projekt.net
6 # info@zero-projekt.net
7 # This file is part of Zero "Was vom Morgen blieb"
8 #
9 # The Zero-Projekt codebase is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the
21 # Free Software Foundation, Inc.,
22 # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 # ###################################################
24
25 """ An advanced layer tool for FIFedit """
26
27 import fife
28 import scripts.plugin as plugin
29 import scripts.editor
30 from scripts.events import *
31 from scripts.gui.action import Action
32 import pychan
33 import pychan.widgets as widgets
34 from pychan.tools import callbackWithArguments as cbwa
35
36 # default should be pychan default, highlight can be choosen (format: r,g,b)
37 _DEFAULT_BACKGROUND_COLOR = pychan.internal.DEFAULT_STYLE['default']['base_color']
38 _HIGHLIGHT_BACKGROUND_COLOR = pychan.internal.DEFAULT_STYLE['default']['selection_color']
39
40 # the dynamicly created widgets have the name scheme prefix + layerid
41 _LABEL_NAME_PREFIX = "select_"
42
43 class LayerTool(plugin.Plugin):
44 """ The B{LayerTool} is an advanced method to view
45 and change layer informations.
46
47 While the original FIFedit tool only allows to select
48 layers, this one will provide the following functionality:
49
50 - toggle layer visibility
51 - select layer
52 - list layers
53
54 """
55 def __init__(self):
56 self._editor = None
57 self._enabled = False
58 self._mapview = None
59
60 self._showAction = None
61
62 self.subwrappers = []
63
64 #--- Plugin function ---#
65 def enable(self):
66 if self._enabled is True:
67 return
68
69 # Fifedit plugin data
70 self._editor = scripts.editor.getEditor()
71 self._showAction = Action(u"LayerTool", checkable=True)
72 scripts.gui.action.activated.connect(self.toggle, sender=self._showAction)
73 self._editor._toolsMenu.addAction(self._showAction)
74
75 self.__create_gui()
76
77 self.toggle()
78
79 events.postMapShown.connect(self.update)
80
81 def disable(self):
82 if self._enabled is False:
83 return
84 self.container.setDocked(False)
85 self.container.hide()
86 self.removeAllChildren()
87
88 events.postMapShown.disconnect(self.update)
89
90 self._editor._toolsMenu.removeAction(self._showAction)
91
92 def isEnabled(self):
93 return self._enabled;
94
95 def getName(self):
96 return u"Layertool"
97
98 #--- End plugin functions ---#
99
100 def __create_gui(self):
101 """ create the basic gui container """
102 self.container = pychan.loadXML('gui/layertool.xml')
103 self.wrapper = self.container.findChild(name="layers_wrapper")
104 self.update(None)
105
106 def _adjust_position(self):
107 """ adjusts the position of the container - we don't want to
108 let the window appear at the center of the screen.
109 (new default position: left, beneath the tools window)
110 """
111 self.container.position = (50, 200)
112
113 def clear(self):
114 """ remove all subwrappers """
115 if self.subwrappers is []: return
116
117 for subwrapper in self.subwrappers:
118 self.wrapper.removeChild(subwrapper)
119
120 self.subwrappers = []
121
122 def update(self, mapview):
123 """ Dump new layer informations into the wrapper
124
125 We group one ToggleButton and one Label into a HBox, the main wrapper
126 itself is a VBox and we also capture both the Button and the Label to listen
127 for mouse actions
128 """
129 layers = []
130 self._mapview = mapview
131 if self._mapview is not None:
132 layers = self._mapview.getMap().getLayers()
133
134 self.clear()
135
136 if len(layers) <= 0:
137 layerid = "No layers"
138 subwrapper = pychan.widgets.HBox()
139
140 layer_name_widget = pychan.widgets.Label()
141 layer_name_widget.text = unicode(layerid)
142 layer_name_widget.name = _LABEL_NAME_PREFIX + layerid
143 subwrapper.addChild(layer_name_widget)
144
145 self.wrapper.addChild(subwrapper)
146 self.subwrappers.append(subwrapper)
147
148 active_layer = self.getActiveLayer()
149 if active_layer:
150 active_layer = active_layer.getId()
151 for layer in reversed(layers):
152 layerid = layer.getId()
153 subwrapper = pychan.widgets.HBox()
154
155 visibility_widget = pychan.widgets.ToggleButton(hexpand=0, up_image="gui/icons/is_visible.png", down_image="gui/icons/is_visible.png", hover_image="gui/icons/is_visible.png")
156 visibility_widget.name = "toggle_" + layerid
157 if layer.areInstancesVisible():
158 visibility_widget.toggled = True
159 visibility_widget.capture(self.toggle_layer_visibility,"mousePressed")
160
161 layer_name_widget = pychan.widgets.Label()
162 layer_name_widget.text = unicode(layerid)
163 layer_name_widget.name = _LABEL_NAME_PREFIX + layerid
164 layer_name_widget.capture(self.select_active_layer,"mousePressed")
165
166 if active_layer == layerid:
167 layer_name_widget.background_color = _HIGHLIGHT_BACKGROUND_COLOR
168 layer_name_widget.foreground_color = _HIGHLIGHT_BACKGROUND_COLOR
169 layer_name_widget.base_color = _HIGHLIGHT_BACKGROUND_COLOR
170
171 subwrapper.addChild(visibility_widget)
172 subwrapper.addChild(layer_name_widget)
173
174 self.wrapper.addChild(subwrapper)
175 self.subwrappers.append(subwrapper)
176
177 self.container.adaptLayout()
178
179 def toggle_layer_visibility(self, event, widget):
180 """ Callback for ToggleButtons
181
182 Toggle the chosen layer visible / invisible
183
184 NOTE:
185 - if a layer is set to invisible, it also shouldn't be the active layer anymore
186
187 @type event: object
188 @param event: pychan mouse event
189 @type widget: object
190 @param widget: the pychan widget where the event occurs, transports the layer id in it's name
191 """
192
193 layerid = widget.name[len(_LABEL_NAME_PREFIX):]
194
195 layer = self._mapview.getMap().getLayer(layerid)
196 active_layer = self.getActiveLayer()
197 if active_layer:
198 active_layer = active_layer.getId()
199
200 if layer.areInstancesVisible():
201 layer.setInstancesVisible(False)
202 else:
203 layer.setInstancesVisible(True)
204
205 if active_layer == layerid:
206 self.select_no_layer()
207
208
209 def select_no_layer(self):
210 """ the exception approach - as soon as the user hides a layer, the mapedit module should stop to use this
211 one, too.
212
213 A bunch of exceptions is the result (each click on the map will result in a exception as no layer is set etc...)
214 """
215 previous_active_layer = self.getActiveLayer()
216 if previous_active_layer is not None:
217 previous_layer_id = previous_active_layer.getId()
218 previous_active_widget = self.container.findChild(name=_LABEL_NAME_PREFIX + previous_layer_id)
219 previous_active_widget.background_color = _DEFAULT_BACKGROUND_COLOR
220 previous_active_widget.foreground_color = _DEFAULT_BACKGROUND_COLOR
221 previous_active_widget.base_color = _DEFAULT_BACKGROUND_COLOR
222 previous_active_widget.text = unicode(previous_layer_id)
223
224 self._mapview.getController().selectLayer(None)
225
226 def getActiveLayer(self):
227 """ Returns the active layer """
228 if self._mapview:
229 return self._mapview.getController()._layer
230
231 def select_active_layer(self, event, widget):
232 """ callback for Labels
233
234 We hand the layerid over to the mapeditor module to select a
235 new active layer
236
237 Additionally, we mark the active layer widget (changing base color) and reseting the previous one
238
239 @type event: object
240 @param event: pychan mouse event
241 @type widget: object
242 @param widget: the pychan widget where the event occurs, transports the layer id in it's name
243 """
244
245 self.select_no_layer()
246
247 layerid = widget.name[7:]
248
249 widget.background_color = _HIGHLIGHT_BACKGROUND_COLOR
250 widget.foreground_color = _HIGHLIGHT_BACKGROUND_COLOR
251 widget.base_color = _HIGHLIGHT_BACKGROUND_COLOR
252 self.container.adaptLayout()
253
254 self._mapview.getController().selectLayer(layerid)
255
256 def toggle(self):
257 if self.container.isVisible() or self.container.isDocked():
258 self.container.setDocked(False)
259 self.container.hide()
260
261 self._showAction.setChecked(False)
262 else:
263 self.container.show()
264 self._showAction.setChecked(True)
265 self._adjust_position()