Mercurial > fife-parpg
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clients/editor/plugins/LayerTool.py Mon Jun 08 16:00:02 2009 +0000 @@ -0,0 +1,265 @@ +#!/usr/bin/env python +# coding: utf-8 +# ################################################### +# Copyright (C) 2008 The Zero-Projekt team +# http://zero-projekt.net +# info@zero-projekt.net +# This file is part of Zero "Was vom Morgen blieb" +# +# The Zero-Projekt codebase is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# ################################################### + +""" An advanced layer tool for FIFedit """ + +import fife +import scripts.plugin as plugin +import scripts.editor +from scripts.events import * +from scripts.gui.action import Action +import pychan +import pychan.widgets as widgets +from pychan.tools import callbackWithArguments as cbwa + +# default should be pychan default, highlight can be choosen (format: r,g,b) +_DEFAULT_BACKGROUND_COLOR = pychan.internal.DEFAULT_STYLE['default']['base_color'] +_HIGHLIGHT_BACKGROUND_COLOR = pychan.internal.DEFAULT_STYLE['default']['selection_color'] + +# the dynamicly created widgets have the name scheme prefix + layerid +_LABEL_NAME_PREFIX = "select_" + +class LayerTool(plugin.Plugin): + """ The B{LayerTool} is an advanced method to view + and change layer informations. + + While the original FIFedit tool only allows to select + layers, this one will provide the following functionality: + + - toggle layer visibility + - select layer + - list layers + + """ + def __init__(self): + self._editor = None + self._enabled = False + self._mapview = None + + self._showAction = None + + self.subwrappers = [] + + #--- Plugin function ---# + def enable(self): + if self._enabled is True: + return + + # Fifedit plugin data + self._editor = scripts.editor.getEditor() + self._showAction = Action(u"LayerTool", checkable=True) + scripts.gui.action.activated.connect(self.toggle, sender=self._showAction) + self._editor._toolsMenu.addAction(self._showAction) + + self.__create_gui() + + self.toggle() + + events.postMapShown.connect(self.update) + + def disable(self): + if self._enabled is False: + return + self.container.setDocked(False) + self.container.hide() + self.removeAllChildren() + + events.postMapShown.disconnect(self.update) + + self._editor._toolsMenu.removeAction(self._showAction) + + def isEnabled(self): + return self._enabled; + + def getName(self): + return u"Layertool" + + #--- End plugin functions ---# + + def __create_gui(self): + """ create the basic gui container """ + self.container = pychan.loadXML('gui/layertool.xml') + self.wrapper = self.container.findChild(name="layers_wrapper") + self.update(None) + + def _adjust_position(self): + """ adjusts the position of the container - we don't want to + let the window appear at the center of the screen. + (new default position: left, beneath the tools window) + """ + self.container.position = (50, 200) + + def clear(self): + """ remove all subwrappers """ + if self.subwrappers is []: return + + for subwrapper in self.subwrappers: + self.wrapper.removeChild(subwrapper) + + self.subwrappers = [] + + def update(self, mapview): + """ Dump new layer informations into the wrapper + + We group one ToggleButton and one Label into a HBox, the main wrapper + itself is a VBox and we also capture both the Button and the Label to listen + for mouse actions + """ + layers = [] + self._mapview = mapview + if self._mapview is not None: + layers = self._mapview.getMap().getLayers() + + self.clear() + + if len(layers) <= 0: + layerid = "No layers" + subwrapper = pychan.widgets.HBox() + + layer_name_widget = pychan.widgets.Label() + layer_name_widget.text = unicode(layerid) + layer_name_widget.name = _LABEL_NAME_PREFIX + layerid + subwrapper.addChild(layer_name_widget) + + self.wrapper.addChild(subwrapper) + self.subwrappers.append(subwrapper) + + active_layer = self.getActiveLayer() + if active_layer: + active_layer = active_layer.getId() + for layer in reversed(layers): + layerid = layer.getId() + subwrapper = pychan.widgets.HBox() + + 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") + visibility_widget.name = "toggle_" + layerid + if layer.areInstancesVisible(): + visibility_widget.toggled = True + visibility_widget.capture(self.toggle_layer_visibility,"mousePressed") + + layer_name_widget = pychan.widgets.Label() + layer_name_widget.text = unicode(layerid) + layer_name_widget.name = _LABEL_NAME_PREFIX + layerid + layer_name_widget.capture(self.select_active_layer,"mousePressed") + + if active_layer == layerid: + layer_name_widget.background_color = _HIGHLIGHT_BACKGROUND_COLOR + layer_name_widget.foreground_color = _HIGHLIGHT_BACKGROUND_COLOR + layer_name_widget.base_color = _HIGHLIGHT_BACKGROUND_COLOR + + subwrapper.addChild(visibility_widget) + subwrapper.addChild(layer_name_widget) + + self.wrapper.addChild(subwrapper) + self.subwrappers.append(subwrapper) + + self.container.adaptLayout() + + def toggle_layer_visibility(self, event, widget): + """ Callback for ToggleButtons + + Toggle the chosen layer visible / invisible + + NOTE: + - if a layer is set to invisible, it also shouldn't be the active layer anymore + + @type event: object + @param event: pychan mouse event + @type widget: object + @param widget: the pychan widget where the event occurs, transports the layer id in it's name + """ + + layerid = widget.name[len(_LABEL_NAME_PREFIX):] + + layer = self._mapview.getMap().getLayer(layerid) + active_layer = self.getActiveLayer() + if active_layer: + active_layer = active_layer.getId() + + if layer.areInstancesVisible(): + layer.setInstancesVisible(False) + else: + layer.setInstancesVisible(True) + + if active_layer == layerid: + self.select_no_layer() + + + def select_no_layer(self): + """ the exception approach - as soon as the user hides a layer, the mapedit module should stop to use this + one, too. + + A bunch of exceptions is the result (each click on the map will result in a exception as no layer is set etc...) + """ + previous_active_layer = self.getActiveLayer() + if previous_active_layer is not None: + previous_layer_id = previous_active_layer.getId() + previous_active_widget = self.container.findChild(name=_LABEL_NAME_PREFIX + previous_layer_id) + previous_active_widget.background_color = _DEFAULT_BACKGROUND_COLOR + previous_active_widget.foreground_color = _DEFAULT_BACKGROUND_COLOR + previous_active_widget.base_color = _DEFAULT_BACKGROUND_COLOR + previous_active_widget.text = unicode(previous_layer_id) + + self._mapview.getController().selectLayer(None) + + def getActiveLayer(self): + """ Returns the active layer """ + if self._mapview: + return self._mapview.getController()._layer + + def select_active_layer(self, event, widget): + """ callback for Labels + + We hand the layerid over to the mapeditor module to select a + new active layer + + Additionally, we mark the active layer widget (changing base color) and reseting the previous one + + @type event: object + @param event: pychan mouse event + @type widget: object + @param widget: the pychan widget where the event occurs, transports the layer id in it's name + """ + + self.select_no_layer() + + layerid = widget.name[7:] + + widget.background_color = _HIGHLIGHT_BACKGROUND_COLOR + widget.foreground_color = _HIGHLIGHT_BACKGROUND_COLOR + widget.base_color = _HIGHLIGHT_BACKGROUND_COLOR + self.container.adaptLayout() + + self._mapview.getController().selectLayer(layerid) + + def toggle(self): + if self.container.isVisible() or self.container.isDocked(): + self.container.setDocked(False) + self.container.hide() + + self._showAction.setChecked(False) + else: + self.container.show() + self._showAction.setChecked(True) + self._adjust_position()