Models.py 7.87 KB
Newer Older
1 2
# -*- coding: utf-8 -*-
"""
3
$Id$
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

Copyright 2011 Lars Kruse <devel@sumpfralle.de>

This file is part of PyCAM.

PyCAM 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 3 of the License, or
(at your option) any later version.

PyCAM 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 PyCAM.  If not, see <http://www.gnu.org/licenses/>.
"""

# imported later (on demand)
#import gtk

import pycam.Plugins
Lars Kruse's avatar
Lars Kruse committed
27
from pycam.Utils import get_non_conflicting_name
28

29

30 31
_GTK_COLOR_MAX = 65535.0

32 33 34 35

class Models(pycam.Plugins.ListPluginBase):

    UI_FILE = "models.ui"
36
    CATEGORIES = ["Model"]
37
    ICONS = {"visible": "visible.svg", "hidden": "visible_off.svg"}
38
    FALLBACK_COLOR = {"red": 0.5, "green": 0.5, "blue": 1.0, "alpha": 1.0}
39 40 41 42

    def setup(self):
        if self.gui:
            import gtk
43
            self._gtk = gtk
44 45 46
            self.model_frame = self.gui.get_object("ModelBox")
            self.model_frame.unparent()
            self.core.register_ui("main", "Models", self.model_frame, weight=-50)
47 48 49 50 51
            model_handling_obj = self.gui.get_object("ModelHandlingNotebook")
            def clear_model_handling_obj():
                for index in range(model_handling_obj.get_n_pages()):
                    model_handling_obj.remove_page(0)
            def add_model_handling_item(item, name):
52
                model_handling_obj.append_page(item, self._gtk.Label(name))
53 54 55
            self.core.register_ui_section("model_handling",
                    add_model_handling_item, clear_model_handling_obj)
            self._modelview = self.gui.get_object("ModelView")
56 57 58
            self.set_gtk_modelview(self._modelview)
            self.register_model_update(lambda:
                    self.core.emit_event("model-list-changed"))
59 60 61 62
            for action, obj_name in ((self.ACTION_UP, "ModelMoveUp"),
                    (self.ACTION_DOWN, "ModelMoveDown"),
                    (self.ACTION_DELETE, "ModelDelete"),
                    (self.ACTION_CLEAR, "ModelDeleteAll")):
63
                self.register_list_action_button(action,
64
                        self.gui.get_object(obj_name))
65 66 67 68
            self._gtk_handlers = []
            self._gtk_handlers.extend((
                    (self.gui.get_object("ModelColorButton"), "color-set",
                        self._set_colors_of_selected_models),
69 70
                    (self._modelview, "row-activated", self._toggle_visibility),
                    (self.gui.get_object("NameCell"), "edited",
71
                        self._edit_model_name)))
72 73
            self._treemodel = self.gui.get_object("ModelList")
            self._treemodel.clear()
74 75
            selection = self._modelview.get_selection()
            selection.set_mode(self._gtk.SELECTION_MULTIPLE)
76 77
            self._gtk_handlers.append((selection, "changed",
                    "model-selection-changed"))
78 79 80
            self._event_handlers = (
                    ("model-selection-changed", self._get_colors_of_selected_models),
                    ("model-list-changed", self._trigger_table_update))
81 82
            self.register_gtk_handlers(self._gtk_handlers)
            self.register_event_handlers(self._event_handlers)
83
            self._get_colors_of_selected_models()
84 85
            # update the model list
            self.core.emit_event("model-list-changed")
86 87
        self.core.register_namespace("models",
                pycam.Plugins.get_filter(self))
88
        self.core.set("models", self)
89
        self.register_state_item("models", self)
90 91
        return True

92
    def teardown(self):
93
        self.clear_state_items()
94
        self.core.unregister_namespace("models")
95 96 97
        if self.gui:
            self.core.unregister_ui_section("model_handling")
            self.core.unregister_ui("main", self.gui.get_object("ModelBox"))
98
            self.core.unregister_ui("main", self.model_frame)
99 100
            self.unregister_gtk_handlers(self._gtk_handlers)
            self.unregister_event_handlers(self._event_handlers)
101
        self.core.set("models", None)
102 103
        while len(self) > 0:
            self.pop()
104 105
        return True

106 107 108 109 110 111
    def _get_colors_of_selected_models(self, widget=None):
        color_button = self.gui.get_object("ModelColorButton")
        models = self.get_selected()
        color_button.set_sensitive(bool(models))
        if models:
            # use the color of the first model
112 113 114 115 116 117
            col = models[0]["color"]
            color_button.set_color(self._gtk.gdk.Color(
                    red=int(col["red"] * _GTK_COLOR_MAX),
                    green=int(col["green"] * _GTK_COLOR_MAX),
                    blue=int(col["blue"] * _GTK_COLOR_MAX)))
            color_button.set_alpha(int(col["alpha"] * _GTK_COLOR_MAX))
118 119 120

    def _set_colors_of_selected_models(self, widget=None):
        color_button = self.gui.get_object("ModelColorButton")
121
        color = color_button.get_color()
122 123
        models = self.get_selected()
        for model in models:
124 125 126 127
            model["color"] = {"red": color.red / _GTK_COLOR_MAX,
                    "green": color.green / _GTK_COLOR_MAX,
                    "blue": color.blue / _GTK_COLOR_MAX,
                    "alpha": color_button.get_alpha() / _GTK_COLOR_MAX}
128 129
        self.core.emit_event("visual-item-updated")

130 131
    def _trigger_table_update(self):
        self.gui.get_object("NameColumn").set_cell_data_func(
Lars Kruse's avatar
Lars Kruse committed
132
                self.gui.get_object("NameCell"), self._visualize_model_name)
133 134 135 136
        self.gui.get_object("VisibleColumn").set_cell_data_func(
                self.gui.get_object("VisibleSymbol"),
                self._visualize_visible_state)

137
    def _edit_model_name(self, cell, path, new_text):
138 139
        model = self.get_by_path(path)
        if model and (new_text != model["name"]) and new_text:
140 141
            model["name"] = new_text

Lars Kruse's avatar
Lars Kruse committed
142
    def _visualize_model_name(self, column, cell, model, m_iter):
143 144
        model_obj = self.get_by_path(model.get_path(m_iter))
        cell.set_property("text", model_obj["name"])
145 146

    def _visualize_visible_state(self, column, cell, model, m_iter):
Lars Kruse's avatar
Lars Kruse committed
147
        model_dict = self.get_by_path(model.get_path(m_iter))
148
        visible = model_dict["visible"]
149 150 151 152
        if visible:
            cell.set_property("pixbuf", self.ICONS["visible"])
        else:
            cell.set_property("pixbuf", self.ICONS["hidden"])
153 154 155 156 157 158 159
        color = model_dict["color"]
        cell.set_property("cell-background-gdk", self._gtk.gdk.Color(
                red=int(color["red"] * _GTK_COLOR_MAX),
                green=int(color["green"] * _GTK_COLOR_MAX),
                blue=int(color["blue"] * _GTK_COLOR_MAX)))

    def _toggle_visibility(self, treeview, path, clicked_column):
Lars Kruse's avatar
Lars Kruse committed
160
        model = self.get_by_path(path)
161
        model["visible"] = not model["visible"]
162 163 164
        self.core.emit_event("visual-item-updated")

    def get_visible(self):
165 166
        return [model for model in self if model["visible"]]

167 168 169 170 171 172
    def get_by_uuid(self, uuid):
        for model in self:
            if model["uuid"] == uuid:
                return model
        return None

sumpfralle's avatar
sumpfralle committed
173 174
    def add_model(self, model, name=None, name_template="Model #%d",
            color=None):
175 176
        model_dict = ModelEntity(model)
        if not name:
Lars Kruse's avatar
Lars Kruse committed
177 178
            name = get_non_conflicting_name(name_template,
                    [model["name"] for model in self])
179
        model_dict["name"] = name
sumpfralle's avatar
sumpfralle committed
180 181
        if not color:
            color = self.core.get("color_model")
182 183 184 185 186 187 188 189 190 191 192
        if not color:
            color = self.FALLBACK_COLOR.copy()
        model_dict["color"] = color
        model_dict["visible"] = True
        self.append(model_dict)


class ModelEntity(pycam.Plugins.ObjectWithAttributes):

    def __init__(self, model):
        super(ModelEntity, self).__init__("model")
193
        self.model = model
194