Exemplo n.º 1
0
    def __init__(self,
                 parent,
                 operation_stack_cb,
                 group="editje/collapsable/default"):
        if not operation_stack_cb:
            raise TypeError("You must set a callback for operation stacking on"
                            " EditjeDetails objects.")

        elementary.Layout.__init__(self, parent)
        self.file_set(parent.themeext, group)
        self._edje = self.edje_get()

        self._parent = parent
        self._operation_stack_cb = operation_stack_cb

        self._proptable = PropertyTable(parent, "main",
                                        self.prop_value_changed)
        self._proptable.show()
        self.e = parent.e

        self._min_sizes_init(group)

        self._box = elementary.Box(parent)
        self._box.pack_end(self._proptable)
        self._box.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self._box.size_hint_align_set(evas.EVAS_HINT_FILL, 0.0)
        self._box.show()
        self.content_set("cl.content", self._box)
        self.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self.size_hint_align_set(evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL)
        self.size_hint_min_set(*self._min_size_collapsed)

        self._subgroups = dict()

        self._open_load()
Exemplo n.º 2
0
    def __init__(self, parent, operation_stack_cb,
                 group="editje/collapsable/default"):
        if not operation_stack_cb:
            raise TypeError("You must set a callback for operation stacking on"
                            " EditjeDetails objects.")

        elementary.Layout.__init__(self, parent)
        self.file_set(parent.theme, group)
        self._edje = self.edje_get()

        self._parent = parent
        self._operation_stack_cb = operation_stack_cb

        self._proptable = PropertyTable(
            parent, "main", self.prop_value_changed)
        self._proptable.show()
        self.e = parent.e

        self._min_sizes_init(group)

        self._box = elementary.Box(parent)
        self._box.pack_end(self._proptable)
        self._box.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self._box.size_hint_align_set(evas.EVAS_HINT_FILL, 0.0)
        self._box.show()
        self.content_set("cl.content", self._box)
        self.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self.size_hint_align_set(evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL)
        self.size_hint_min_set(*self._min_size_collapsed)

        self._subgroups = dict()

        self._open_load()
Exemplo n.º 3
0
    def _header_init(self, parent):
        self.title = "part state"

        self._header_table = PropertyTable(parent, "state name")

        prop = Property(parent, "state")
        wid = WidgetStates(self, self.e, self._operation_stack_cb)
        wid.tooltip_set("Unique state name for part.<br>"
                        "'default 0.0' is immutable.")
        prop.widget_add("s", wid)
        self._header_table.property_add(prop)
        # FIXME: ugly and dangerous: overriding property_add's behavior on
        # widget's changed callback
        wid.changed = self._state_entry_changed_cb

        self.content_set("part_state.swallow", self._header_table)
Exemplo n.º 4
0
    def _header_init(self, parent):
        self.title = "part frame properties"

        self._header_table = PropertyTable(parent, "part name/type")
        self.content_set("part_state.swallow", self._header_table)

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "type")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        prop.widget_add("t", wid)
        self._header_table.property_add(prop)

        self._source_prop = Property(parent, "source widget")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        self._source_prop.widget_add("s", wid)
        self._header_table.property_add(self._source_prop)
        self._source_prop.hide()

        self._module_prop = Property(parent, "module")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        self._module_prop.widget_add("m", wid)
        self._header_table.property_add(self._module_prop)
        self._module_prop.hide()

        self.content_set("part_name.swallow", self._header_table)
        self.e.animation.callback_add("animation.changed", self._anim_selected)
        self.e.animation.callback_add("animation.unselected",
                                      self._anim_unselected)
        self.e.animation.callback_add("part.added", self._anim_parts_changed)
        self.e.animation.callback_add("part.removed", self._anim_parts_changed)

        self._state_copy_button = StateCopyButton(self.e)

        self.edje_get().signal_callback_add(
            "cl,option,clicked", "editje/collapsable",
            self._state_copy_button._floater_open)
Exemplo n.º 5
0
    def group_add(self, name):
        if name in self._subgroups:
            raise KeyError(name)

        tbl = PropertyTable(self._parent, name, self.prop_value_changed)
        tbl.show()
        frm = elementary.Layout(self._parent)

        frm.file_set(self._parent.themeext, "subgroup")
        frm.edje_get().part_text_set("title.label", name)
        frm.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        frm.size_hint_align_set(evas.EVAS_HINT_FILL, 0.0)
        frm.content_set("content", tbl)
        frm.show()
        self._box.pack_end(frm)

        grp = dict()
        grp["table"] = tbl
        grp["frame"] = frm
        self._subgroups[name] = grp
Exemplo n.º 6
0
    def group_add(self, name):
        if name in self._subgroups:
            raise KeyError(name)

        tbl = PropertyTable(self._parent, name, self.prop_value_changed)
        tbl.show()
        frm = elementary.Layout(self._parent)

        frm.file_set(self._parent.theme, "subgroup")
        frm.edje_get().part_text_set("title.label", name)
        frm.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        frm.size_hint_align_set(evas.EVAS_HINT_FILL, 0.0)
        frm.content_set("content", tbl)
        frm.show()
        self._box.pack_end(frm)

        grp = dict()
        grp["table"] = tbl
        grp["frame"] = frm
        self._subgroups[name] = grp
Exemplo n.º 7
0
    def _header_init(self, parent):
        self.title = "part state"

        self._header_table = PropertyTable(parent, "state name")

        prop = Property(parent, "state")
        wid = WidgetStates(self, self.e, self._operation_stack_cb)
        wid.tooltip_set("Unique state name for part.<br>"
                        "'default 0.0' is immutable.")
        prop.widget_add("s", wid)
        self._header_table.property_add(prop)
        # FIXME: ugly and dangerous: overriding property_add's behavior on
        # widget's changed callback
        wid.changed = self._state_entry_changed_cb

        self.content_set("part_state.swallow", self._header_table)
Exemplo n.º 8
0
    def _header_init(self, parent):
        self.title = "part frame properties"

        self._header_table = PropertyTable(parent, "part name/type")
        self.content_set("part_state.swallow", self._header_table)

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "type")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        prop.widget_add("t", wid)
        self._header_table.property_add(prop)

        self._source_prop = Property(parent, "source widget")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        self._source_prop.widget_add("s", wid)
        self._header_table.property_add(self._source_prop)
        self._source_prop.hide()

        self._module_prop = Property(parent, "module")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        self._module_prop.widget_add("m", wid)
        self._header_table.property_add(self._module_prop)
        self._module_prop.hide()

        self.content_set("part_name.swallow", self._header_table)
        self.e.animation.callback_add("animation.changed", self._anim_selected)
        self.e.animation.callback_add("animation.unselected",
                                      self._anim_unselected)
        self.e.animation.callback_add("part.added", self._anim_parts_changed)
        self.e.animation.callback_add("part.removed", self._anim_parts_changed)

        self._state_copy_button = StateCopyButton(self.e)

        self.edje_get().signal_callback_add(
            "cl,option,clicked", "editje/collapsable",
            self._state_copy_button._floater_open)
Exemplo n.º 9
0
class PartStateDetails(EditjeDetails):
    state_pop_min_w = 200
    state_pop_min_h = 300

    def __init__(self,
                 parent,
                 operation_stack_cb,
                 img_new_img_cb=None,
                 img_list_get_cb=None,
                 img_id_get_cb=None,
                 fnt_new_fnt_cb=None,
                 fnt_list_get_cb=None,
                 workfile_name_get_cb=None,
                 part_object_get_cb=None,
                 group="editje/collapsable/part_state"):
        EditjeDetails.__init__(self, parent, operation_stack_cb, group)

        self._aspect_prefs = \
            ['NONE', 'VERTICAL', 'HORIZONTAL', 'BOTH', 'SOURCE' ]

        self._header_init(parent)
        self.focus_custom_chain_set([self._header_table, self._box])

        self._img_new_img_cb = img_new_img_cb
        self._img_list_get_cb = img_list_get_cb
        self._img_id_get_cb = img_id_get_cb
        self._fnt_new_fnt_cb = fnt_new_fnt_cb
        self._fnt_list_get_cb = fnt_list_get_cb
        self._workfile_name_get_cb = workfile_name_get_cb
        self._part_object_get_cb = part_object_get_cb

        self._update_schedule = None
        self.on_del_add(self._del_handler)

        self._external_type = None

        self._common_props_create()
        self._rel_props_create()
        self._image_props_create()
        self._text_props_create()
        self._external_props_create()

        self.e.callback_add("group.changed", self._edje_load)
        self.e.callback_add("part.removed", self._part_removed)
        self.e.part.callback_add("part.changed", self._part_update)
        # self.e.part.callback_add("name.changed", self._part_update)
        self.e.part.callback_add("part.unselected", self._part_unselected)
        self.e.part.state.callback_add("state.changed", self._state_changed_cb)

        for event in [
                "state.rel1.changed", "state.rel2.changed",
                "state.color.changed", "state.text.changed",
                "state.font.changed", "state.text_size.changed"
        ]:
            self.e.part.state.callback_add(event,
                                           self._state_common_props_changed_cb)

        self.e.part.state.callback_add("part.state.min.changed",
                                       self._update_min)
        self.e.part.state.callback_add("part.state.max.changed",
                                       self._update_max)
        self._hide_all()

        self.open_disable = False
        self.open = True
        self.part_edje = None
        self.part_evas = None

    def _prop_object_get(self):
        return self.e.part.state

    def _prop_old_values_get(self, prop_attrs, is_external):
        old_values = []
        state = self._prop_object_get()

        for i, p in enumerate(prop_attrs):
            if is_external[i]:
                type_, old_value = state.external_param_get(p)
                if (type_ == edje.EDJE_EXTERNAL_PARAM_TYPE_STRING or type_ == \
                        edje.EDJE_EXTERNAL_PARAM_TYPE_CHOICE) and \
                        old_value is None:
                    old_values.append("")
                else:
                    old_values.append(old_value)
            else:
                old_values.append(getattr(state, p))

        return old_values

    def _header_init(self, parent):
        self.title = "part state"

        self._header_table = PropertyTable(parent, "state name")

        prop = Property(parent, "state")
        wid = WidgetStates(self, self.e, self._operation_stack_cb)
        wid.tooltip_set("Unique state name for part.<br>"
                        "'default 0.0' is immutable.")
        prop.widget_add("s", wid)
        self._header_table.property_add(prop)
        # FIXME: ugly and dangerous: overriding property_add's behavior on
        # widget's changed callback
        wid.changed = self._state_entry_changed_cb

        self.content_set("part_state.swallow", self._header_table)

    def _del_handler(self, o):
        if self._update_schedule is not None:
            self._update_schedule.delete()
            self._update_schedule = None

    def _edje_load(self, emissor, data):
        self.editable = self.e.edje

    def _part_update(self, emissor, data):
        if self.part_evas:
            self.part_evas.on_resize_del(self._size_changed)
        self.part_edje = self.e.part._part
        self.part_evas = self._part_object_get_cb(self.part_edje.name)
        self.part_evas.on_resize_add(self._size_changed)
        self._size_changed(self.part_evas)
        state, val = self.part_edje.state_selected_get()
        if state == "(null)":
            state = "default"
        self._header_table["state"].value = "%s %.2f" % (state, val)
        self._header_table["state"].show_value()
        self.state = self.part_edje.state_get(state, val)
        self._update()
        self.show()

    def _part_unselected(self, emissor, data):
        if not self.e.part:
            return

        if self.part_evas:
            self.part_evas.on_resize_del(self._size_changed)
            self.part_evas = None

        self._header_table["state"].value = None
        self._header_table["state"].hide_value()
        self._hide_all()
        self.hide()

    def _part_removed(self, emissor, data):
        self.part_edje = None
        self.part_evas = None

    def _common_props_create(self):
        prop = Property(self._parent, "min")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Minimum part<br>width in pixels.")
        prop.widget_add("w", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Minimum part<br>height in pixels.")
        prop.widget_add("h", wid)
        self["main"].property_add(prop)

        prop = Property(self._parent, "max")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Maximum part<br>width in pixels.<br>0 = disabled")
        prop.widget_add("w", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Maximum part<br>height in pixels.<br>0 = disabled")
        prop.widget_add("h", wid)
        self["main"].property_add(prop)

        # 'step' not implemented in edje_edit

        prop = Property(self._parent, "current")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Current part<br>height in pixels.")
        prop.widget_add("w", wid)
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Current part<br>width in pixels.")
        prop.widget_add("h", wid)
        self["main"].property_add(prop)

        prop = Property(self._parent, "visible")
        wid = WidgetBoolean(self)
        wid.tooltip_set("Change part's visibility.")
        prop.widget_add("v", wid)
        self["main"].property_add(prop)

        prop = Property(self._parent, "align")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Part horizontal align.<br>0.0 = left  1.0 = right")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Part vertical align.<br>0.0 = top  1.0 = bottom")
        prop.widget_add("y", wid)
        self["main"].property_add(prop)

        # 'fixed' not implemented in edje_edit
        # 'aspect' and 'aspect_preference' missing

        prop = Property(self._parent, "color")
        wid = WidgetColor(self, self.e)
        wid.tooltip_set(
            "Part main color.<br>"
            "Enter color in integers or<br>"
            "in Hexa notation.", "Preview of main color.<br>"
            "Click to edit it.")
        prop.widget_add("c", wid)
        self["main"].property_add(prop)

    def _text_props_create(self):
        self.group_add("text")
        # missing: text_class
        # not implemented in edje_edit: min, max

        prop = Property(self._parent, "text")
        wid = WidgetEntry(self)
        wid.tooltip_set("Set the text of part.")
        prop.widget_add("t", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "font")
        wid = WidgetFont(self._parent, \
                         self._fnt_new_fnt_cb, self._fnt_list_get_cb, \
                         self._workfile_name_get_cb)
        wid.tooltip_set("Change the text's font.")
        prop.widget_add("f", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "size")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Change text font's size.")
        prop.widget_add("s", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "fit")
        prop.widget_add("x", WidgetBoolean(self))
        prop.widget_add("y", WidgetBoolean(self))
        self["text"].property_add(prop)

        prop = Property(self._parent, "align")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Text horizontal align.<br>0.0 = left  1.0 = right")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Text vertical align.<br>0.0 = top  1.0 = bottom")
        prop.widget_add("y", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "elipsis")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Cut text if biggest then part's area.<br>"
                        "0.0 = fix the left side  1.0 = right side")
        prop.widget_add("e", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "color2")
        wid = WidgetColor(self, self.e)
        wid.tooltip_set(
            "Text shadow color.<br>"
            "Enter color in integers or<br>"
            "in Hexa notation.", "Preview of text shadow color.<br>"
            "Click to edit it.")
        prop.widget_add("c", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "color3")
        wid = WidgetColor(self, self.e)
        wid.tooltip_set(
            "Text outline color.<br>"
            "Enter color in integers or<br>"
            "in Hexa notation.", "Preview of text outline color.<br>"
            "Click to edit it.")
        prop.widget_add("c", wid)
        self["text"].property_add(prop)

    def _image_props_create(self):
        self.group_add("image")

        prop = Property(self._parent, "normal")
        wid = WidgetButton(self)
        wid.clicked = self._image_btn_clicked
        wid.tooltip_set("Actual image.<br>Click to change it.")
        prop.widget_add("n", wid)
        self["image"].property_add(prop)

        prop = Property(self._parent, "border")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Lenght of left border in pixels.<br>"
                        "Left border isn't horizontal scalable.")
        prop.widget_add("l", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Lenght of right border in pixels.<br>"
                        "Right border isn't horizontal scalable.")
        prop.widget_add("r", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Lenght of top border in pixels.<br>"
                        "Top border isn't vertical scalable.")
        prop.widget_add("t", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Lenght of bottom border in pixels.<br>"
                        "Bottom border isn't vertical scalable.")
        prop.widget_add("b", wid)
        self["image"].property_add(prop)

        prop = Property(self._parent, "middle")
        wid = WidgetBoolean(self)
        wid.states_set("Solid", "None")
        wid.tooltip_set("Enables painting of image middle.<br>"
                        "If 'None', the image middle is hidden.")
        prop.widget_add("m", wid)
        self["image"].property_add(prop)

        prop = Property(self._parent, "aspect_pref")
        wid = WidgetCombo(self)
        for null, i in enumerate(self._aspect_prefs):
            wid.item_add(i)
        #FIXME: the 'aspect' property is not yet exposed ;)
        wid.tooltip_set("Sets the scope of the \"aspect\" property to " +
                        "a given dimension")
        prop.widget_add("a", wid)
        self["image"].property_add(prop)


#        wid = WidgetBoolean(self)
#        wid.states_set("Dynamic", "Static")
#        self.prop_add("scale_hint", wid)

    def _rel_props_create(self):
        rel_to_box_title = "Placement reference"

        self.group_add("rel1")
        self.group_title_set("rel1", "top-left")

        def parts_get():
            return self.e.parts

        def sel_part_get():
            return self.e.part.name

        popup_hide_cb_list = [(self.e.part, "part.unselected"),
                              (self.e.part, "part.changed")]

        prop = Property(self._parent, "to")
        wid = WidgetButtonList(self, rel_to_box_title, parts_get, sel_part_get,
                               popup_hide_cb_list)
        wid.tooltip_set("Left reference part.")
        prop.widget_add("x", wid)
        wid = WidgetButtonList(self, rel_to_box_title, parts_get, sel_part_get,
                               popup_hide_cb_list)
        wid.tooltip_set("Top reference part.")
        prop.widget_add("y", wid)
        self["rel1"].property_add(prop)

        prop = Property(self._parent, "relative")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Left relative position to<br>"
                        "reference part.<br>"
                        "0.0 = 0%/begining  1.0 = 100%/end")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Top relative position to<br>"
                        "reference part.<br>"
                        "0.0 = 0%/begining  1.0 = 100%/end")
        prop.widget_add("y", wid)
        self["rel1"].property_add(prop)

        prop = Property(self._parent, "offset")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Left offset from relative<br>" "position in pixels.")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Top offset from relative<br>" "position in pixels.")
        prop.widget_add("y", wid)
        self["rel1"].property_add(prop)

        self.group_add("rel2")
        self.group_title_set("rel2", "bottom-right")

        prop = Property(self._parent, "to")
        wid = WidgetButtonList(self, rel_to_box_title, parts_get, sel_part_get,
                               popup_hide_cb_list)
        wid.tooltip_set("Right reference part.")
        prop.widget_add("x", wid)
        wid = WidgetButtonList(self, rel_to_box_title, parts_get, sel_part_get,
                               popup_hide_cb_list)
        wid.tooltip_set("Bottom reference part.")
        prop.widget_add("y", wid)
        self["rel2"].property_add(prop)

        prop = Property(self._parent, "relative")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Right relative position to<br>"
                        "reference part.<br>"
                        "0.0 = 0%/begining  1.0 = 100%/end")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Bottom relative position to<br>"
                        "reference part.<br>"
                        "0.0 = 0%/begining  1.0 = 100%/end")
        prop.widget_add("y", wid)
        self["rel2"].property_add(prop)

        prop = Property(self._parent, "offset")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        prop.widget_add("x", wid)
        wid.tooltip_set("Right offset from relative<br>"
                        "position in pixels.<br>"
                        "default = -1 (see docs)")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Bottom offset from relative<br>"
                        "position in pixels.<br>"
                        "default = -1 (see docs)")
        prop.widget_add("y", wid)
        self["rel2"].property_add(prop)

    def _external_props_create(self):
        self.group_add("external")

    def _image_btn_clicked(self, *args):
        ImageSelectionWizard(
            self._parent,
            self._image_selected_cb,
            self._img_new_img_cb,
            self._img_list_get_cb,
            self._img_id_get_cb,
            self._workfile_name_get_cb,
        ).show()

    def _image_selected_cb(self, image):
        self.prop_value_changed("normal", image, "image")

    def _state_changed_cb(self, emissor, data):
        if not data:
            return
        self.part_edje.state_selected_set(*data)
        self.state = self.e.part.state._state
        prop = self._header_table.get("state")
        if prop:
            prop.value = "%s %.2f" % data
        self._update()

    def _state_common_props_changed_cb(self, emissor, data):
        self._update()

    def _state_entry_changed_cb(self, st_widget, *args, **kwargs):
        def state_rename(part_name, old_name, new_name):
            # select 1st
            if self.e.part.name != part_name:
                self.e.part.name = part_name
            self.e.part.state.name = old_name[0]

            part = self.e.part_get(part_name)

            if (part.state_exist(*new_name)) or old_name == ["default", 0.0]:
                return False

            # rename later
            return self.e.part.state.rename(*new_name)

        part = self.e.part.name
        old_name = self.e.part.state.name

        new_name = st_widget.value.split(None, 1)
        if len(new_name) == 1:
            new_name[1] = 0.0
        else:
            new_name[1] = float(new_name[1])

        if state_rename(part, old_name, new_name):
            op = Operation("state renaming")

            op.redo_callback_add(state_rename, part, old_name, new_name)
            op.undo_callback_add(state_rename, part, new_name, old_name)
            self._operation_stack_cb(op)
        else:
            # TODO: notify the user of renaming failure
            st_widget.value = "%s %.2f" % old_name

    def _hide_all(self):
        self.main_hide()
        self.group_hide("rel1")
        self.group_hide("rel2")
        self.group_hide("text")
        self.group_hide("image")
        self.group_hide("external")
        self.edje_get().signal_emit("cl,option,disable", "editje")

    def _update(self):
        if self._update_schedule is not None:
            self._update_schedule.delete()
        self._update_schedule = ecore.idler_add(self._update_do)

    def _update_do(self):
        self._update_schedule = None
        self._hide_all()

        if not self.e.part.state.name[0]:
            return

        self._update_common()

        self.main_show()
        self.group_show("rel1")
        self.group_show("rel2")
        if self.part_edje.type == edje.EDJE_PART_TYPE_TEXT:
            self._update_text()
            self.group_show("text")
        elif self.part_edje.type == edje.EDJE_PART_TYPE_IMAGE:
            self._update_image()
            self.group_show("image")
        elif self.part_edje.type == edje.EDJE_PART_TYPE_EXTERNAL:
            self._update_external()
            self.group_show("external")
        self.edje_get().signal_emit("cl,option,enable", "editje")
        return False

    def _update_min(self, emissor, data):
        self["main"]["min"].value = data

    def _update_max(self, emissor, data):
        self["main"]["max"].value = data

    def _update_common(self):
        self._update_min(self, self.e.part.state.min)
        self._update_max(self, self.e.part.state.max)

        self["main"]["align"].value = self.state.align_get()
        self["main"]["color"].value = self.state.color_get()
        self["main"]["visible"].value = self.state.visible

        x, y = self.state.rel1_to_get()
        self["rel1"]["to"].value = x, y
        self["rel1"]["relative"].value = self.state.rel1_relative_get()
        self["rel1"]["offset"].value = self.state.rel1_offset_get()

        x, y = self.state.rel2_to_get()
        self["rel2"]["to"].value = x, y
        self["rel2"]["relative"].value = self.state.rel2_relative_get()
        self["rel2"]["offset"].value = self.state.rel2_offset_get()

    def _update_text(self):
        t = self.state.text_get()
        self["text"]["text"].value = t
        f = self.state.font_get()
        if f is None:
            f = ""
        self["text"]["font"].value = f
        self["text"]["size"].value = self.state.text_size_get()
        self["text"]["fit"].value = self.state.text_fit_get()
        self["text"]["align"].value = self.state.text_align_get()
        self["text"]["color2"].value = self.state.color2_get()
        self["text"]["color3"].value = self.state.color3_get()
        self["text"]["elipsis"].value = str(self.state.text_elipsis_get())

    def _update_image(self):
        img = self.state.image_get()
        self["image"]["normal"].value = img
        self["image"]["border"].value = self.state.image_border_get()
        self["image"]["middle"].value = self.state.image_border_fill_get()
        self["image"]["aspect_pref"].value = \
            self._aspect_prefs[self.state.aspect_pref_get()]

    def _create_props_by_type(self, edje_type):
        edje_type = edje.external_type_get(edje_type)
        self._params_info = edje_type.parameters_info_get()
        for p in self._params_info:
            prop = Property(self._parent, p.name)
            if p.type == edje.EDJE_EXTERNAL_PARAM_TYPE_BOOL:
                wid = WidgetBoolean(self)
                wid.states_set(p.true_string, p.false_string)
            elif p.type == edje.EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
                wid = WidgetCombo(self._parent)
                for choice in p.choices:
                    wid.item_add(choice)
            else:
                wid = WidgetEntry(self)
                if p.type == edje.EDJE_EXTERNAL_PARAM_TYPE_INT:
                    wid.type_int()
                elif p.type == edje.EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
                    wid.type_float()
            prop.widget_add("v", wid)
            self["external"].property_add(prop)

    def _update_external(self):
        t = self.part_edje.source
        if t != self._external_type:
            self._external_type = t
            self["external"].clear()
            self._create_props_by_type(t)
        for p in self.state.external_params_get():
            self["external"][p.name].value = p.value

    def prop_value_changed(self, prop_name, prop_value, group_name):
        if group_name == "main":
            self._prop_common_value_changed(prop_name, prop_value)
        elif group_name == "rel1":
            self._prop_rel1_value_changed(prop_name, prop_value)
        elif group_name == "rel2":
            self._prop_rel2_value_changed(prop_name, prop_value)
        elif group_name == "text":
            self._prop_text_value_changed(prop_name, prop_value)
        elif group_name == "image":
            self._prop_image_value_changed(prop_name, prop_value)
        elif group_name == "external":
            self._prop_external_value_changed(prop_name, prop_value)

        self.editable.calc_force()

    def _prop_common_value_changed(self, prop, value):
        args = [["main"], [prop], [value], [None], [False], [None]]
        if prop == "min":
            self._prop_change_do("part state mininum size setting", *args)
        elif prop == "max":
            self._prop_change_do("part state maximum size setting", *args)
        elif prop == "color":
            self._prop_change_do("part state color setting", *args)
        elif prop == "visible":
            self._prop_change_do("part state visibility setting", *args)
        elif prop == "align":
            self._prop_change_do("part state alignment setting", *args)

    def _check_state_relto_void(self):
        state = self.e.part.state
        rel1_to, rel2_to = state.rel1_to, state.rel2_to
        if (rel1_to == (None, None) and rel2_to == (None, None)):
            return True
        return False

    def _relto_fill_args(self, relto):
        return [["rel1", "rel2", "rel1", "rel2", "rel1", "rel2"],
                ["to", "to", "relative", "relative", "offset", "offset"],
                [relto, relto, [0.0, 0.0], [1.0, 1.0], [0, 0], [-1, -1]],
                [
                    "rel1_to", "rel2_to", "rel1_relative", "rel2_relative",
                    "rel1_offset", "rel2_offset"
                ], [False, False, False, False, False, False],
                [None, None, None, None, None, None]]

    def _prop_rel1_value_changed(self, prop, value):
        if prop == "to":
            if self._check_state_relto_void():
                if value[0]:
                    value = [value[0], value[0]]
                else:
                    value = [value[1], value[1]]
                args = self._relto_fill_args(value)
            else:
                args = [["rel1"], [prop], [value], ["rel1_to"], [False],
                        [None]]
            self._prop_change_do(
                "part state relative positioning setting (top-left corner's"
                " origin part)", *args)
        elif prop == "relative":
            args = [["rel1"], [prop], [value], ["rel1_relative"], [False],
                    [None]]
            self._prop_change_do(
                "part state relative positioning setting (top-left corner's"
                " relative position WRT origin's dimensions)", *args)
        elif prop == "offset":
            args = [["rel1"], [prop], [value], ["rel1_offset"], [False],
                    [None]]
            self._prop_change_do(
                "part state relative positioning setting (top-left corner's"
                " additional offset)", *args)

    def _prop_rel2_value_changed(self, prop, value):
        if prop == "to":
            if self._check_state_relto_void():
                if value[0]:
                    value = [value[0], value[0]]
                else:
                    value = [value[1], value[1]]
                args = self._relto_fill_args(value)
            else:
                args = [["rel2"], [prop], [value], ["rel2_to"], [False],
                        [None]]
            self._prop_change_do(
                "part state relative positioning setting (bottom-right"
                " corner's origin part)", *args)
        elif prop == "relative":
            args = [["rel2"], [prop], [value], ["rel2_relative"], [False],
                    [None]]
            self._prop_change_do(
                "part state relative positioning setting (bottom-right"
                " corner's relative position WRT origin's dimensions)", *args)
        elif prop == "offset":
            args = [["rel2"], [prop], [value], ["rel2_offset"], [False],
                    [None]]
            self._prop_change_do(
                "part state relative positioning setting (bottom-right"
                " corner's additional offset)", *args)

    def _prop_text_value_changed(self, prop, value):
        if prop == "text":
            args = [["text"], [prop], [value], [None], [False], [None]]
            self._prop_change_do("part state text string setting", *args)
        elif prop == "font":
            args = [["text"], [prop], [value], [None], [False], [None]]
            self._prop_change_do("part state text font setting", *args)
        elif prop == "size":
            args = [["text"], [prop], [value], ["text_size"], [False], [None]]
            self._prop_change_do("part state text size setting", *args)
        elif prop == "fit":
            args = [["text"], [prop], [value], ["text_fit"], [False], [None]]
            self._prop_change_do("part state text fit to given axis setting",
                                 *args)
        elif prop == "align":
            args = [["text"], [prop], [value], ["text_align"], [False], [None]]
            self._prop_change_do("part state text alignment setting", *args)
        elif prop == "color2":
            args = [["text"], [prop], [value], [None], [False], [None]]
            self._prop_change_do("part state text shadow color setting", *args)
        elif prop == "color3":
            args = [["text"], [prop], [value], [None], [False], [None]]
            self._prop_change_do("part state text outline color setting",
                                 *args)
        elif prop == "elipsis":
            args = [["text"], [prop], [value], ["text_elipsis"], [False],
                    [None]]
            self._prop_change_do("part state text elipsis (balancing) setting",
                                 *args)

    def _prop_image_value_changed(self, prop, value):
        if prop == "normal":
            # FIXME: note that undoing an image set from <nothing> to some img
            # won't reset the img part at all: edje was not really meant to
            # have "void" img parts. img part addition should raise the img
            # wizard dialog to choose an initial img from.
            args = [["image"], [prop], [value], ["image"], [False], [None]]
            self._prop_change_do("part state image setting", *args)
        elif prop == "border":
            args = [["image"], [prop], [value], ["image_border"], [False],
                    [None]]
            self._prop_change_do("part state image border setting", *args)
        elif prop == "middle":
            args = [["image"], [prop], [value], ["image_border_fill"], [False],
                    [None]]
            self._prop_change_do("part state \"middle\" setting", *args)
        elif prop == "aspect_pref":
            args = [["image"], [prop], [self._aspect_prefs.index(value)],
                    [None], [False], [lambda x: self._aspect_prefs[x]]]
            self._prop_change_do("part state image aspect preference setting",
                                 *args)

    def _prop_external_value_changed(self, prop, value):
        for p in self._params_info:
            if p.name == prop:
                if not p.validate(value):
                    nil, old_value = self.state.external_param_get(prop)
                    self["external"][prop].value = old_value
                    return
        args = [["external"], [prop], [value], [None], [True], [None]]
        self._prop_change_do("(external) part state \"%s\" setting" % prop,
                             *args)

    def _size_changed(self, obj):
        self["main"]["current"].value = obj.size
        if self.part_edje.type == edje.EDJE_PART_TYPE_IMAGE:
            obj.fill_set(0, 0, *obj.size)
Exemplo n.º 10
0
class EditjeDetails(elementary.Layout):
    def __init__(self, parent, operation_stack_cb,
                 group="editje/collapsable/default"):
        if not operation_stack_cb:
            raise TypeError("You must set a callback for operation stacking on"
                            " EditjeDetails objects.")

        elementary.Layout.__init__(self, parent)
        self.file_set(parent.theme, group)
        self._edje = self.edje_get()

        self._parent = parent
        self._operation_stack_cb = operation_stack_cb

        self._proptable = PropertyTable(
            parent, "main", self.prop_value_changed)
        self._proptable.show()
        self.e = parent.e

        self._min_sizes_init(group)

        self._box = elementary.Box(parent)
        self._box.pack_end(self._proptable)
        self._box.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self._box.size_hint_align_set(evas.EVAS_HINT_FILL, 0.0)
        self._box.show()
        self.content_set("cl.content", self._box)
        self.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self.size_hint_align_set(evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL)
        self.size_hint_min_set(*self._min_size_collapsed)

        self._subgroups = dict()

        self._open_load()

    def _min_sizes_init(self, group):
        self._m_save = self._edje.size_min_calc()
        self._min_size_collapsed = self._m_save
        self._edje.signal_emit("cl,extra,activate", "")
        edje.message_signal_process()
        self._m_save_extra = self._edje.size_min_calc()
        self._edje.signal_emit("cl,extra,deactivate", "")
        self._min_size = self._min_size_collapsed

    def min_size_expanded_toggle(self, value):
        if value:
            self._min_size_collapsed = self._m_save_extra
        else:
            self._min_size_collapsed = self._m_save

    def _size_hint_changed_cb(self, obj):
        self._min_size = self._edje.size_min_calc()
        if self._open:
            self.size_hint_min_set(*self._min_size)

    def content_set(self, part, obj):
        obj.on_changed_size_hints_add(self._size_hint_changed_cb)
        elementary.Layout.content_set(self, part, obj)
        self._min_size = self._edje.size_min_calc()

    def group_add(self, name):
        if name in self._subgroups:
            raise KeyError(name)

        tbl = PropertyTable(self._parent, name, self.prop_value_changed)
        tbl.show()
        frm = elementary.Layout(self._parent)

        frm.file_set(self._parent.theme, "subgroup")
        frm.edje_get().part_text_set("title.label", name)
        frm.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        frm.size_hint_align_set(evas.EVAS_HINT_FILL, 0.0)
        frm.content_set("content", tbl)
        frm.show()
        self._box.pack_end(frm)

        grp = dict()
        grp["table"] = tbl
        grp["frame"] = frm
        self._subgroups[name] = grp

    def group_title_set(self, name, title):
        if not name in self._subgroups:
            raise KeyError(name)

        self._subgroups[name]["frame"].edje_get().part_text_set("title.label",
                                                                title)

    def group_show(self, name):
        if not name in self._subgroups:
            raise KeyError(name)
        grp = self._subgroups[name]["frame"]
        self._box.pack_end(grp)
        grp.show()

    def group_hide(self, name):
        if not name in self._subgroups:
            raise KeyError(name)
        grp = self._subgroups[name]["frame"]
        self._box.unpack(grp)
        grp.hide()

    def main_hide(self):
        self._box.unpack(self._proptable)
        self._proptable.hide()

    def main_show(self):
        self._box.pack_end(self._proptable)
        self._proptable.show()

    def prop_value_changed(self, prop, value, group):
        pass

    def __getitem__(self, key):
        if key == "main":
            return self._proptable
        elif key in self._subgroups:
            return self._subgroups[key]["table"]
        raise KeyError(key)

    # Title
    def _title_set(self, value):
        self._edje.part_text_set("cl.header.title", value)

    def _title_get(self):
        return self.part_text_get("cl.header.title")

    title = property(_title_get, _title_set)

    #  Open / Close
    def _open_load(self):
        self._edje.signal_callback_add("cl,opened", "editje/collapsable",
                                 self._opened_cb)
        self._edje.signal_callback_add("cl,closed", "editje/collapsable",
                                 self._closed_cb)

        self._open = False
        self._open_disable = True
        self.open = False

    def _open_set(self, value):
        if self._open_disable:
            return
        self.open_set(value)

    def open_set(self, value):
        if value:
            self._edje.signal_emit("cl,open", "")
        else:
            self._edje.signal_emit("cl,close", "")

    def _opened_cb(self, obj, emission, source):
        self._open = True
        self.size_hint_weight_set(evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND)
        self.size_hint_min_set(*self._min_size)
        self._edje.calc_force()
        self._proptable.disabled_set(False)

    def _closed_cb(self, obj, emission, source):
        self._open = False
        self.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self.size_hint_min_set(*self._min_size_collapsed)
        self._edje.calc_force()
        self._proptable.disabled_set(True)

    def _open_get(self):
        return self._open

    open = property(_open_get, _open_set)

    def _open_disable_set(self, value):
        if value:
            self.edje_get().signal_emit("cl,disable", "")
        else:
            self.edje_get().signal_emit("cl,enable", "")
        self._open_disable = value

    def _open_disable_get(self, value):
        return self._open_disable

    open_disable = property(_open_disable_get, _open_disable_set)

    # most general form, specialise if needed
    def _context_recall(self, **kargs):
        self.e.part.name = kargs["part"]
        self.e.part.state.name = kargs["state"]

    # most general form, specialise if needed
    def _prop_old_values_get(self, prop_attrs, is_external):
        old_values = []
        obj = self._prop_object_get()

        for i, p in enumerate(prop_attrs):
            old_values.append(getattr(obj, p))

        return old_values

    def _prop_change_do(self, op_name, prop_groups, prop_names, prop_values,
                        prop_attrs, is_external, filters):

        def set_property(part_name, state_name, anim_name, frame, sig_name,
                         prop_attrs, prop_names, prop_values, is_external,
                         filter_, reverse=False):

            if reverse:
                efunc = lambda l: izip(xrange(len(l) - 1, -1, -1), reversed(l))
            else:
                efunc = enumerate

            self._context_recall(
                part=part_name, state=state_name, animation=anim_name,
                time=frame, signal=sig_name)

            for i, p in efunc(prop_attrs):
                if is_external[i]:
                    if not self.e.part.state.external_param_set(prop_attrs[i],
                            prop_values[i]):
                        return i
                else:
                    obj = self._prop_object_get()
                    setattr(obj, prop_attrs[i], prop_values[i])

                if filter_[i]:
                    label_value = filter_[i](prop_values[i])
                else:
                    label_value = prop_values[i]
                if self[prop_groups[i]][prop_names[i]].value != label_value:
                    self[prop_groups[i]][prop_names[i]].value = label_value
            return True

        if not self._prop_object_get:
            raise NotImplementedError(
                "One must implement self._prop_object_get for"
                " EditjeDetails children classes.")

        l = len(prop_groups)
        for arg in (prop_names, prop_values, prop_attrs,
                    is_external, filters):
            if len(arg) != l:
                raise TypeError("Cardinality of property fields differ.")

        part_name = self.e.part.name
        state_name = self.e.part.state.name

        # animations' only
        anim_name = self.e.animation.name
        frame = self.e.animation.state

        # signals' only
        sig_name = self.e.signal.name

        old_values = []
        for i, p in enumerate(prop_attrs):
            if not p:
                prop_attrs[i] = prop_names[i]

        old_values = self._prop_old_values_get(prop_attrs, is_external)

        is_valid = set_property(part_name, state_name, anim_name, frame,
                                sig_name, prop_attrs, prop_names, prop_values,
                                is_external, filters)

        if is_valid is not True:
            self["external"][prop_attrs[is_valid]].value = old_values[is_valid]
            return

        op = Operation(op_name)
        op.redo_callback_add(
            set_property, part_name, state_name, anim_name, frame, sig_name,
            prop_attrs, prop_names, prop_values, is_external, filters)
        op.undo_callback_add(
            set_property, part_name, state_name, anim_name, frame, sig_name,
            prop_attrs, prop_names, old_values, is_external, filters, True)
        self._operation_stack_cb(op)

        return op
Exemplo n.º 11
0
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(self,
                               parent,
                               operation_stack_cb,
                               group="editje/collapsable/part_properties")

        self.title = "animation"

        self._transitions = [
            'None', 'Linear', 'Sinusoidal', 'Accelerate', 'Decelerate'
        ]

        self._header_table = PropertyTable(parent, "animation name",
                                           self.header_prop_value_changed)
        self.content_set("part_name.swallow", self._header_table)
        self.focus_custom_chain_set([self._header_table, self._box])

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Unique animation name.")
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "length")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Time lenght of animation<br>in seconds.")
        prop.widget_add("l", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "current")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of current keyframe<br>in seconds.")
        prop.widget_add("c", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "previous")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of previous keyframe<br>in seconds.")
        prop.widget_add("p", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "next")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of next keyframe<br>in seconds.")
        prop.widget_add("n", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "transition")
        wid = WidgetCombo(parent)
        for null, i in enumerate(self._transitions):
            wid.item_add(i)
        wid.tooltip_set("Transition effect to interpolation<br>"
                        "between the previous keyframe<br>and this.")
        prop.widget_add("type", wid)
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Transition time between the<br>"
                        "previous keyframe and this,<br>in seconds.")
        prop.widget_add("length", wid)
        self["main"].property_add(prop)

        self._parent.main_edje.signal_callback_add("timestop", "*",
                                                   self._timeline_cb)
        self._parent.main_edje.signal_callback_add("timeremove", "*",
                                                   self._timeremove_cb)
        self.e.callback_add("animation.removed", self._removed)
        self.e.animation.callback_add("animation.changed", self._update)
        self.e.animation.callback_add("animation.unselected", self._removed)
        self.e.animation.callback_add("state.added", self._timestop_add)
        self.e.animation.callback_add("frame.changed", self._update_states)
Exemplo n.º 12
0
class AnimationDetails(EditjeDetails):
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(self,
                               parent,
                               operation_stack_cb,
                               group="editje/collapsable/part_properties")

        self.title = "animation"

        self._transitions = [
            'None', 'Linear', 'Sinusoidal', 'Accelerate', 'Decelerate'
        ]

        self._header_table = PropertyTable(parent, "animation name",
                                           self.header_prop_value_changed)
        self.content_set("part_name.swallow", self._header_table)
        self.focus_custom_chain_set([self._header_table, self._box])

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Unique animation name.")
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "length")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Time lenght of animation<br>in seconds.")
        prop.widget_add("l", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "current")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of current keyframe<br>in seconds.")
        prop.widget_add("c", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "previous")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of previous keyframe<br>in seconds.")
        prop.widget_add("p", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "next")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of next keyframe<br>in seconds.")
        prop.widget_add("n", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "transition")
        wid = WidgetCombo(parent)
        for null, i in enumerate(self._transitions):
            wid.item_add(i)
        wid.tooltip_set("Transition effect to interpolation<br>"
                        "between the previous keyframe<br>and this.")
        prop.widget_add("type", wid)
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Transition time between the<br>"
                        "previous keyframe and this,<br>in seconds.")
        prop.widget_add("length", wid)
        self["main"].property_add(prop)

        self._parent.main_edje.signal_callback_add("timestop", "*",
                                                   self._timeline_cb)
        self._parent.main_edje.signal_callback_add("timeremove", "*",
                                                   self._timeremove_cb)
        self.e.callback_add("animation.removed", self._removed)
        self.e.animation.callback_add("animation.changed", self._update)
        self.e.animation.callback_add("animation.unselected", self._removed)
        self.e.animation.callback_add("state.added", self._timestop_add)
        self.e.animation.callback_add("frame.changed", self._update_states)

    def _removed(self, emissor, data):
        self.open_disable = True
        self._header_table["name"].value = "Unselected"
        self._header_table["name"].value_obj._values_dict["n"].disabled_set(
            True)
        self._header_table["length"].value = None
        self["main"]["current"].hide_value()
        self["main"]["previous"].hide_value()
        self["main"]["next"].hide_value()
        self["main"]["transition"].hide_value()
        self["main"]["transition"].value_obj._values_dict["type"].hover_end()
        self._timeline_clear()
        self._parent.main_edje.signal_emit("timeline,block", "")
        self.open = False
        self.open_disable = True

    def _update(self, emissor, data):
        self.open_disable = False
        self._header_table["name"].value = data
        self._header_table["name"].value_obj._values_dict["n"].disabled_set(
            False)
        self._header_table["length"].value = "%.1gs" % self.e.animation.length
        self._last_timestamp = 0.0
        self._timeline_update()
        self._parent.main_edje.signal_emit("timeline,unblock", "")

        self.open_disable = False
        self.open = True
        self.show()

    def _timeline_cb(self, obj, emission, source):
        t = float(source)
        if not t in self.e.animation.timestops:
            anim_name = self.e.animation.name
            anim_frame = self.e.animation.state
            self.e.animation.state_add(t)
            op = Operation("animation (%s) frame (%s) creation" % \
                               (self.e.animation.name, t))
            op.redo_callback_add(self._state_add, t, anim_name)
            op.redo_callback_add(setattr, self.e.animation, "state", t)
            op.undo_callback_add(self._remove_time_point, t, anim_name,
                                 anim_frame)
            self._operation_stack_cb(op)

        self.e.animation.state = t

    def _state_add(self, t, anim_name):
        self._context_recall(animation=anim_name)
        self.e.animation.state_add(t)

    def _remove_time_point(self, t, anim_name, anim_frame):
        self._context_recall(animation=anim_name, time=anim_frame)
        prog = "@%s@%.2f" % (self.e.animation.name, t)
        self.e.animation.state_prev_goto()
        self.e.animation.state_del(t)
        self.e.program_del(prog)
        self._parent.main_edje.signal_emit("ts,%.1g,disable" % t, "editje")
        self._parent.main_edje.signal_emit("ts,%.1g,unselected" % t, "editje")

    def _frame_readd(self, t, anim_name, saved_states, trans):
        self.e.animation.name = anim_name
        self.e.animation.state_add(t)
        for pname, state in saved_states:
            self.e.part.name = pname
            st = self.e.part_get(pname).state_get(state.name)
            state.apply_to(st)
        self.e.animation.state = t
        self.e.animation.program.transition = trans
        self.e.animation.event_emit("frame.changed")

    def _timeremove_cb(self, obj, emission, source):
        t = float(source)
        anim_name = self.e.animation.name
        anim_frame = self.e.animation.state
        prog = "@%s@%.2f" % (anim_name, t)

        saved_states = []
        for part_name in self.e.animation.parts:
            part = self.e.part_get(part_name)
            st_obj = part.state_get(prog)
            st_class = objects_data.state_class_from_part_type_get(part)
            state_save = st_class(st_obj)
            saved_states.append([part.name, state_save])

        trans = self.e.animation.program.transition

        def agree(bt, notification):
            self._remove_time_point(t, anim_name, anim_frame)
            notification.hide()
            notification.delete()
            op = Operation("animation (%s) frame (%s) deletion" % \
                               (anim_name, t))
            op.redo_callback_add(self._remove_time_point, t, anim_name,
                                 anim_frame)
            op.undo_callback_add(self._frame_readd, t, anim_name, saved_states,
                                 trans)
            self._operation_stack_cb(op)

        def disagree(bt, notification):
            notification.hide()
            notification.delete()

        if t in self.e.animation.timestops:
            notification = ErrorNotify(
                self._parent, orient=elementary.ELM_NOTIFY_ORIENT_CENTER)
            notification.title = "Do you really want to delete this " \
                "animation frame?"
            notification.action_add("Yes", agree, None, notification)
            notification.action_add("No", disagree, None, notification)
            notification.show()

    def _timeline_clear(self):
        for i in range(0, 11):
            sig = "ts,%.1g," % (i / 10.0)
            self._parent.main_edje.signal_emit(sig + "disable", "editje")
            self._parent.main_edje.signal_emit(sig + "unselected", "editje")

    def _timeline_update(self):
        self._timeline_clear()
        for s in self.e.animation.timestops:
            sig = "ts,%.1g,enable" % s
            self._parent.main_edje.signal_emit(sig, "editje")

    def _timestop_add(self, emissor, data):
        self._parent.main_edje.signal_emit("ts,%.1g,enable" % data, "editje")
        self._header_table["length"].value = "%.1gs" % self.e.animation.length

    def _update_states(self, emissor, data):
        step = self.e.animation.state
        self["main"]["current"].show_value()
        self["main"]["current"].value = str(step)

        prev = self.e.animation.state_prev()
        self["main"]["previous"].show_value()
        if prev is None:
            prev = 0.0
            self["main"]["previous"].value = "None"
        else:
            self["main"]["previous"].value = str(prev)

        next_state = self.e.animation.state_next()
        self["main"]["next"].show_value()
        if next_state is None:
            self["main"]["next"].value = "None"
        else:
            self["main"]["next"].value = str(next_state)

        t = self._transitions[self.e.animation.program.transition]
        self["main"]["transition"].show_value()
        self["main"]["transition"].value = (t, str(step - prev))

        sig = "ts,%.1g,selected" % self.e.animation.state
        self._parent.main_edje.signal_emit(sig, "editje")
        if self.e.animation.state != 0.0:
            sig = "ts,rm,%.1g,selected" % self.e.animation.state
            self._parent.main_edje.signal_emit(sig, "editje")
        sig = "ts,%.1g,unselected" % self._last_timestamp
        if self._last_timestamp != self.e.animation.state:
            self._parent.main_edje.signal_emit(sig, "editje")
            sig = "ts,rm,%.1g,unselected" % self._last_timestamp
            self._parent.main_edje.signal_emit(sig, "editje")
        self._last_timestamp = self.e.animation.state

    def header_prop_value_changed(self, prop, value, group):
        if prop == "name":
            if not self.e.animation.name_set(value):
                self._header_table["name"].value = self.e.animation.name

    def _context_recall(self, **kargs):
        if "animation" in kargs:
            self.e.animation.name = kargs["animation"]
            if "time" in kargs:
                self.e.animation.state = kargs["time"]
        if "part" in kargs:
            self.e.part.name = kargs["part"]
            if "state" in kargs:
                self.e.part.state.name = kargs["state"]

    def _prop_object_get(self):
        return self.e.animation.program

    def prop_value_changed(self, prop, value, group):
        if prop == "transition":
            args = [["main"], [prop], [self._transitions.index(value[0])],
                    [None], [False],
                    [lambda x: (self._transitions[x], value[1])]]

            self._prop_change_do("animation state transition", *args)
Exemplo n.º 13
0
class PartStateDetails(EditjeDetails):
    state_pop_min_w = 200
    state_pop_min_h = 300

    def __init__(self, parent, operation_stack_cb, img_new_img_cb=None,
                 img_list_get_cb=None, img_id_get_cb=None,
                 fnt_new_fnt_cb=None, fnt_list_get_cb=None,
                 workfile_name_get_cb=None, part_object_get_cb=None,
                 group="editje/collapsable/part_state"):
        EditjeDetails.__init__(self, parent, operation_stack_cb, group)

        self._header_init(parent)
        self.focus_custom_chain_set([self._header_table, self._box])

        self._img_new_img_cb = img_new_img_cb
        self._img_list_get_cb = img_list_get_cb
        self._img_id_get_cb = img_id_get_cb
        self._fnt_new_fnt_cb = fnt_new_fnt_cb
        self._fnt_list_get_cb = fnt_list_get_cb
        self._workfile_name_get_cb = workfile_name_get_cb
        self._part_object_get_cb = part_object_get_cb

        self._update_schedule = None
        self.on_del_add(self._del_handler)

        self._external_type = None

        self._common_props_create()
        self._rel_props_create()
        self._image_props_create()
        self._text_props_create()
        self._external_props_create()

        self.e.callback_add("group.changed", self._edje_load)
        self.e.callback_add("part.removed", self._part_removed)
        self.e.part.callback_add("part.changed", self._part_update)
        # self.e.part.callback_add("name.changed", self._part_update)
        self.e.part.callback_add("part.unselected", self._part_unselected)
        self.e.part.state.callback_add("state.changed", self._state_changed_cb)

        for event in ["state.rel1.changed", "state.rel2.changed",
                      "state.color.changed", "state.text.changed",
                      "state.font.changed", "state.text_size.changed"]:
            self.e.part.state.callback_add(
                event, self._state_common_props_changed_cb)

        self.e.part.state.callback_add(
            "part.state.min.changed", self._update_min)
        self.e.part.state.callback_add(
            "part.state.max.changed", self._update_max)
        self._hide_all()

        self.open_disable = False
        self.open = True
        self.part_edje = None
        self.part_evas = None

    def _prop_object_get(self):
        return self.e.part.state

    def _prop_old_values_get(self, prop_attrs, is_external):
        old_values = []
        state = self._prop_object_get()

        for i, p in enumerate(prop_attrs):
            if is_external[i]:
                type_, old_value = state.external_param_get(p)
                if (type_ == edje.EDJE_EXTERNAL_PARAM_TYPE_STRING or type_ == \
                        edje.EDJE_EXTERNAL_PARAM_TYPE_CHOICE) and \
                        old_value is None:
                    old_values.append("")
                else:
                    old_values.append(old_value)
            else:
                old_values.append(getattr(state, p))

        return old_values

    def _header_init(self, parent):
        self.title = "part state"

        self._header_table = PropertyTable(parent, "state name")

        prop = Property(parent, "state")
        wid = WidgetStates(self, self.e, self._operation_stack_cb)
        wid.tooltip_set("Unique state name for part.<br>"
                        "'default 0.0' is immutable.")
        prop.widget_add("s", wid)
        self._header_table.property_add(prop)
        # FIXME: ugly and dangerous: overriding property_add's behavior on
        # widget's changed callback
        wid.changed = self._state_entry_changed_cb

        self.content_set("part_state.swallow", self._header_table)

    def _del_handler(self, o):
        if self._update_schedule is not None:
            self._update_schedule.delete()
            self._update_schedule = None

    def _edje_load(self, emissor, data):
        self.editable = self.e.edje

    def _part_update(self, emissor, data):
        if self.part_evas:
            self.part_evas.on_resize_del(self._size_changed)
        self.part_edje = self.e.part._part
        self.part_evas = self._part_object_get_cb(self.part_edje.name)
        self.part_evas.on_resize_add(self._size_changed)
        self._size_changed(self.part_evas)
        state, val = self.part_edje.state_selected_get()
        if state == "(null)":
            state = "default"
        self._header_table["state"].value = "%s %.2f" % (state, val)
        self._header_table["state"].show_value()
        self.state = self.part_edje.state_get(state, val)
        self._update()
        self.show()

    def _part_unselected(self, emissor, data):
        if not self.e.part:
            return

        if self.part_evas:
            self.part_evas.on_resize_del(self._size_changed)
            self.part_evas = None

        self._header_table["state"].value = None
        self._header_table["state"].hide_value()
        self._hide_all()
        self.hide()

    def _part_removed(self, emissor, data):
        self.part_edje = None
        self.part_evas = None

    def _common_props_create(self):
        prop = Property(self._parent, "min")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Minimum part<br>width in pixels.")
        prop.widget_add("w", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Minimum part<br>height in pixels.")
        prop.widget_add("h", wid)
        self["main"].property_add(prop)

        prop = Property(self._parent, "max")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Maximum part<br>width in pixels.<br>0 = disabled")
        prop.widget_add("w", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Maximum part<br>height in pixels.<br>0 = disabled")
        prop.widget_add("h", wid)
        self["main"].property_add(prop)

        # 'step' not implemented in edje_edit

        prop = Property(self._parent, "current")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Current part<br>height in pixels.")
        prop.widget_add("w", wid)
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Current part<br>width in pixels.")
        prop.widget_add("h", wid)
        self["main"].property_add(prop)

        prop = Property(self._parent, "visible")
        wid = WidgetBoolean(self)
        wid.tooltip_set("Change part's visibility.")
        prop.widget_add("v", wid)
        self["main"].property_add(prop)

        prop = Property(self._parent, "align")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Part horizontal align.<br>0.0 = left  1.0 = right")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Part vertical align.<br>0.0 = top  1.0 = bottom")
        prop.widget_add("y", wid)
        self["main"].property_add(prop)

        # 'fixed' not implemented in edje_edit
        # 'aspect' and 'aspect_preference' missing

        prop = Property(self._parent, "color")
        wid = WidgetColor(self, self.e)
        wid.tooltip_set("Part main color.<br>"
                        "Enter color in integers or<br>"
                        "in Hexa notation.",
                        "Preview of main color.<br>"
                        "Click to edit it.")
        prop.widget_add("c", wid)
        self["main"].property_add(prop)

    def _text_props_create(self):
        self.group_add("text")
        # missing: text_class
        # not implemented in edje_edit: min, max

        prop = Property(self._parent, "text")
        wid = WidgetEntry(self)
        wid.tooltip_set("Set the text of part.")
        prop.widget_add("t", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "font")
        wid = WidgetFont(self._parent, \
                         self._fnt_new_fnt_cb, self._fnt_list_get_cb, \
                         self._workfile_name_get_cb)
        wid.tooltip_set("Change the text's font.")
        prop.widget_add("f", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "size")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Change text font's size.")
        prop.widget_add("s", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "fit")
        prop.widget_add("x", WidgetBoolean(self))
        prop.widget_add("y", WidgetBoolean(self))
        self["text"].property_add(prop)

        prop = Property(self._parent, "align")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Text horizontal align.<br>0.0 = left  1.0 = right")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Text vertical align.<br>0.0 = top  1.0 = bottom")
        prop.widget_add("y", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "elipsis")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Cut text if biggest then part's area.<br>"
                        "0.0 = fix the left side  1.0 = right side")
        prop.widget_add("e", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "color2")
        wid = WidgetColor(self, self.e)
        wid.tooltip_set("Text shadow color.<br>"
                        "Enter color in integers or<br>"
                        "in Hexa notation.",
                        "Preview of text shadow color.<br>"
                        "Click to edit it.")
        prop.widget_add("c", wid)
        self["text"].property_add(prop)

        prop = Property(self._parent, "color3")
        wid = WidgetColor(self, self.e)
        wid.tooltip_set("Text outline color.<br>"
                        "Enter color in integers or<br>"
                        "in Hexa notation.",
                        "Preview of text outline color.<br>"
                        "Click to edit it.")
        prop.widget_add("c", wid)
        self["text"].property_add(prop)

    def _image_props_create(self):
        self.group_add("image")

        prop = Property(self._parent, "normal")
        wid = WidgetButton(self)
        wid.clicked = self._image_btn_clicked
        wid.tooltip_set("Actual image.<br>Click to change it.")
        prop.widget_add("n", wid)
        self["image"].property_add(prop)

        prop = Property(self._parent, "border")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Lenght of left border in pixels.<br>"
                        "Left border isn't horizontal scalable.")
        prop.widget_add("l", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Lenght of right border in pixels.<br>"
                        "Right border isn't horizontal scalable.")
        prop.widget_add("r", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Lenght of top border in pixels.<br>"
                        "Top border isn't vertical scalable.")
        prop.widget_add("t", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Lenght of bottom border in pixels.<br>"
                        "Bottom border isn't vertical scalable.")
        prop.widget_add("b", wid)
        self["image"].property_add(prop)

        prop = Property(self._parent, "middle")
        wid = WidgetBoolean(self)
        wid.states_set("Solid", "None")
        wid.tooltip_set("Enables painting of image middle.<br>"
                        "If 'None', the image middle is hidden.")
        prop.widget_add("m", wid)
        self["image"].property_add(prop)
#        wid = WidgetBoolean(self)
#        wid.states_set("Dynamic", "Static")
#        self.prop_add("scale_hint", wid)

    def _rel_props_create(self):
        rel_to_box_title = "Placement reference"

        self.group_add("rel1")
        self.group_title_set("rel1", "top-left")

        def parts_get():
            return self.e.parts

        def sel_part_get():
            return self.e.part.name

        popup_hide_cb_list = [(self.e.part, "part.unselected"),
                              (self.e.part, "part.changed")]

        prop = Property(self._parent, "to")
        wid = WidgetButtonList(self, rel_to_box_title, parts_get, sel_part_get,
                               popup_hide_cb_list)
        wid.tooltip_set("Left reference part.")
        prop.widget_add("x", wid)
        wid = WidgetButtonList(
                self, rel_to_box_title, parts_get, sel_part_get,
                popup_hide_cb_list)
        wid.tooltip_set("Top reference part.")
        prop.widget_add("y", wid)
        self["rel1"].property_add(prop)

        prop = Property(self._parent, "relative")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Left relative position to<br>"
                        "reference part.<br>"
                        "0.0 = 0%/begining  1.0 = 100%/end")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Top relative position to<br>"
                        "reference part.<br>"
                        "0.0 = 0%/begining  1.0 = 100%/end")
        prop.widget_add("y", wid)
        self["rel1"].property_add(prop)

        prop = Property(self._parent, "offset")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Left offset from relative<br>"
                        "position in pixels.")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Top offset from relative<br>"
                        "position in pixels.")
        prop.widget_add("y", wid)
        self["rel1"].property_add(prop)

        self.group_add("rel2")
        self.group_title_set("rel2", "bottom-right")

        prop = Property(self._parent, "to")
        wid = WidgetButtonList(
                self, rel_to_box_title, parts_get, sel_part_get,
                popup_hide_cb_list)
        wid.tooltip_set("Right reference part.")
        prop.widget_add("x", wid)
        wid = WidgetButtonList(
                self, rel_to_box_title, parts_get, sel_part_get,
                popup_hide_cb_list)
        wid.tooltip_set("Bottom reference part.")
        prop.widget_add("y", wid)
        self["rel2"].property_add(prop)

        prop = Property(self._parent, "relative")
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Right relative position to<br>"
                        "reference part.<br>"
                        "0.0 = 0%/begining  1.0 = 100%/end")
        prop.widget_add("x", wid)
        wid = WidgetEntry(self)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Bottom relative position to<br>"
                        "reference part.<br>"
                        "0.0 = 0%/begining  1.0 = 100%/end")
        prop.widget_add("y", wid)
        self["rel2"].property_add(prop)

        prop = Property(self._parent, "offset")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        prop.widget_add("x", wid)
        wid.tooltip_set("Right offset from relative<br>"
                        "position in pixels.<br>"
                        "default = -1 (see docs)")
        wid = WidgetEntry(self)
        wid.type_int()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: int(x)
        wid.tooltip_set("Bottom offset from relative<br>"
                        "position in pixels.<br>"
                        "default = -1 (see docs)")
        prop.widget_add("y", wid)
        self["rel2"].property_add(prop)

    def _external_props_create(self):
        self.group_add("external")

    def _image_btn_clicked(self, *args):
        ImageSelectionWizard(self._parent, self._image_selected_cb,
               self._img_new_img_cb, self._img_list_get_cb,
               self._img_id_get_cb, self._workfile_name_get_cb,).show()

    def _image_selected_cb(self, image):
        self.prop_value_changed("normal", image, "image")

    def _state_changed_cb(self, emissor, data):
        if not data:
            return
        self.part_edje.state_selected_set(*data)
        self.state = self.e.part.state._state
        prop = self._header_table.get("state")
        if prop:
            prop.value = "%s %.2f" % data
        self._update()

    def _state_common_props_changed_cb(self, emissor, data):
        self._update()

    def _state_entry_changed_cb(self, st_widget, *args, **kwargs):

        def state_rename(part_name, old_name, new_name):
            # select 1st
            if self.e.part.name != part_name:
                self.e.part.name = part_name
            self.e.part.state.name = old_name[0]

            part = self.e.part_get(part_name)

            if (part.state_exist(*new_name)) or old_name == ["default", 0.0]:
                return False

            # rename later
            return self.e.part.state.rename(*new_name)

        part = self.e.part.name
        old_name = self.e.part.state.name

        new_name = st_widget.value.split(None, 1)
        if len(new_name) == 1:
            new_name[1] = 0.0
        else:
            new_name[1] = float(new_name[1])

        if state_rename(part, old_name, new_name):
            op = Operation("state renaming")

            op.redo_callback_add(state_rename, part, old_name, new_name)
            op.undo_callback_add(state_rename, part, new_name, old_name)
            self._operation_stack_cb(op)
        else:
            # TODO: notify the user of renaming failure
            st_widget.value = "%s %.2f" % old_name

    def _hide_all(self):
        self.main_hide()
        self.group_hide("rel1")
        self.group_hide("rel2")
        self.group_hide("text")
        self.group_hide("image")
        self.group_hide("external")
        self.edje_get().signal_emit("cl,option,disable", "editje")

    def _update(self):
        if self._update_schedule is not None:
            self._update_schedule.delete()
        self._update_schedule = ecore.idler_add(self._update_do)

    def _update_do(self):
        self._update_schedule = None
        self._hide_all()

        if not self.e.part.state.name[0]:
            return

        self._update_common()

        self.main_show()
        self.group_show("rel1")
        self.group_show("rel2")
        if self.part_edje.type == edje.EDJE_PART_TYPE_TEXT:
            self._update_text()
            self.group_show("text")
        elif self.part_edje.type == edje.EDJE_PART_TYPE_IMAGE:
            self._update_image()
            self.group_show("image")
        elif self.part_edje.type == edje.EDJE_PART_TYPE_EXTERNAL:
            self._update_external()
            self.group_show("external")
        self.edje_get().signal_emit("cl,option,enable", "editje")
        return False

    def _update_min(self, emissor, data):
        self["main"]["min"].value = data

    def _update_max(self, emissor, data):
        self["main"]["max"].value = data

    def _update_common(self):
        self._update_min(self, self.e.part.state.min)
        self._update_max(self, self.e.part.state.max)

        self["main"]["align"].value = self.state.align_get()
        self["main"]["color"].value = self.state.color_get()
        self["main"]["visible"].value = self.state.visible

        x, y = self.state.rel1_to_get()
        self["rel1"]["to"].value = x, y
        self["rel1"]["relative"].value = self.state.rel1_relative_get()
        self["rel1"]["offset"].value = self.state.rel1_offset_get()

        x, y = self.state.rel2_to_get()
        self["rel2"]["to"].value = x, y
        self["rel2"]["relative"].value = self.state.rel2_relative_get()
        self["rel2"]["offset"].value = self.state.rel2_offset_get()

    def _update_text(self):
        t = self.state.text_get()
        self["text"]["text"].value = t
        f = self.state.font_get()
        if f is None:
            f = ""
        self["text"]["font"].value = f
        self["text"]["size"].value = self.state.text_size_get()
        self["text"]["fit"].value = self.state.text_fit_get()
        self["text"]["align"].value = self.state.text_align_get()
        self["text"]["color2"].value = self.state.color2_get()
        self["text"]["color3"].value = self.state.color3_get()
        self["text"]["elipsis"].value = str(self.state.text_elipsis_get())

    def _update_image(self):
        img = self.state.image_get()
        self["image"]["normal"].value = img
        self["image"]["border"].value = self.state.image_border_get()
        self["image"]["middle"].value = self.state.image_border_fill_get()

    def _create_props_by_type(self, edje_type):
        edje_type = edje.external_type_get(edje_type)
        self._params_info = edje_type.parameters_info_get()
        for p in self._params_info:
            prop = Property(self._parent, p.name)
            if p.type == edje.EDJE_EXTERNAL_PARAM_TYPE_BOOL:
                wid = WidgetBoolean(self)
                wid.states_set(p.true_string, p.false_string)
            elif p.type == edje.EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
                wid = WidgetCombo(self._parent)
                for choice in p.choices:
                    wid.item_add(choice)
            else:
                wid = WidgetEntry(self)
                if p.type == edje.EDJE_EXTERNAL_PARAM_TYPE_INT:
                    wid.type_int()
                elif p.type == edje.EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
                    wid.type_float()
            prop.widget_add("v", wid)
            self["external"].property_add(prop)

    def _update_external(self):
        t = self.part_edje.source
        if t != self._external_type:
            self._external_type = t
            self["external"].clear()
            self._create_props_by_type(t)
        for p in self.state.external_params_get():
            self["external"][p.name].value = p.value

    def prop_value_changed(self, prop_name, prop_value, group_name):
        if group_name == "main":
            self._prop_common_value_changed(prop_name, prop_value)
        elif group_name == "rel1":
            self._prop_rel1_value_changed(prop_name, prop_value)
        elif group_name == "rel2":
            self._prop_rel2_value_changed(prop_name, prop_value)
        elif group_name == "text":
            self._prop_text_value_changed(prop_name, prop_value)
        elif group_name == "image":
            self._prop_image_value_changed(prop_name, prop_value)
        elif group_name == "external":
            self._prop_external_value_changed(prop_name, prop_value)

        self.editable.calc_force()

    def _prop_common_value_changed(self, prop, value):
        args = [["main"], [prop], [value], [None], [False], [None]]
        if prop == "min":
            self._prop_change_do(
                "part state mininum size setting", *args)
        elif prop == "max":
            self._prop_change_do(
                "part state maximum size setting", *args)
        elif prop == "color":
            self._prop_change_do(
                "part state color setting", *args)
        elif prop == "visible":
            self._prop_change_do(
                "part state visibility setting", *args)
        elif prop == "align":
            self._prop_change_do(
                "part state alignment setting", *args)

    def _check_state_relto_void(self):
        state = self.e.part.state
        rel1_to, rel2_to = state.rel1_to, state.rel2_to
        if (rel1_to == (None, None) and rel2_to == (None, None)):
            return True
        return False

    def _relto_fill_args(self, relto):
        return [["rel1", "rel2", "rel1", "rel2", "rel1", "rel2"],
                ["to", "to", "relative", "relative", "offset", "offset"],
                [relto, relto, [0.0, 0.0], [1.0, 1.0], [0, 0], [-1, -1]],
                ["rel1_to", "rel2_to", "rel1_relative", "rel2_relative",
                 "rel1_offset", "rel2_offset"],
                [False, False, False, False, False, False],
                [None, None, None, None, None, None]]

    def _prop_rel1_value_changed(self, prop, value):
        if prop == "to":
            if self._check_state_relto_void():
                if value[0]:
                    value = [value[0], value[0]]
                else:
                    value = [value[1], value[1]]
                args = self._relto_fill_args(value)
            else:
                args = [["rel1"], [prop], [value], ["rel1_to"], [False],
                        [None]]
            self._prop_change_do(
                "part state relative positioning setting (top-left corner's"
                " origin part)", *args)
        elif prop == "relative":
            args = [["rel1"], [prop], [value], ["rel1_relative"], [False],
                    [None]]
            self._prop_change_do(
                "part state relative positioning setting (top-left corner's"
                " relative position WRT origin's dimensions)", *args)
        elif prop == "offset":
            args = [["rel1"], [prop], [value], ["rel1_offset"], [False],
                    [None]]
            self._prop_change_do(
                "part state relative positioning setting (top-left corner's"
                " additional offset)", *args)

    def _prop_rel2_value_changed(self, prop, value):
        if prop == "to":
            if self._check_state_relto_void():
                if value[0]:
                    value = [value[0], value[0]]
                else:
                    value = [value[1], value[1]]
                args = self._relto_fill_args(value)
            else:
                args = [["rel2"], [prop], [value], ["rel2_to"], [False],
                        [None]]
            self._prop_change_do(
                "part state relative positioning setting (bottom-right"
                " corner's origin part)", *args)
        elif prop == "relative":
            args = [["rel2"], [prop], [value], ["rel2_relative"], [False],
                    [None]]
            self._prop_change_do(
                "part state relative positioning setting (bottom-right"
                " corner's relative position WRT origin's dimensions)", *args)
        elif prop == "offset":
            args = [["rel2"], [prop], [value], ["rel2_offset"], [False],
                    [None]]
            self._prop_change_do(
                "part state relative positioning setting (bottom-right"
                " corner's additional offset)", *args)

    def _prop_text_value_changed(self, prop, value):
        if prop == "text":
            args = [["text"], [prop], [value], [None], [False], [None]]
            self._prop_change_do(
                "part state text string setting", *args)
        elif prop == "font":
            args = [["text"], [prop], [value], [None], [False], [None]]
            self._prop_change_do(
                "part state text font setting", *args)
        elif prop == "size":
            args = [["text"], [prop], [value], ["text_size"], [False], [None]]
            self._prop_change_do("part state text size setting", *args)
        elif prop == "fit":
            args = [["text"], [prop], [value], ["text_fit"], [False], [None]]
            self._prop_change_do("part state text fit to given axis setting",
                                 *args)
        elif prop == "align":
            args = [["text"], [prop], [value], ["text_align"], [False], [None]]
            self._prop_change_do("part state text alignment setting", *args)
        elif prop == "color2":
            args = [["text"], [prop], [value], [None], [False], [None]]
            self._prop_change_do("part state text shadow color setting", *args)
        elif prop == "color3":
            args = [["text"], [prop], [value], [None], [False], [None]]
            self._prop_change_do("part state text outline color setting",
                                 *args)
        elif prop == "elipsis":
            args = [["text"], [prop], [value], ["text_elipsis"], [False],
                    [None]]
            self._prop_change_do("part state text elipsis (balancing) setting",
                                 *args)

    def _prop_image_value_changed(self, prop, value):
        if prop == "normal":
            # FIXME: note that undoing an image set from <nothing> to some img
            # won't reset the img part at all: edje was not really meant to
            # have "void" img parts. img part addition should raise the img
            # wizard dialog to choose an initial img from.
            args = [["image"], [prop], [value], ["image"], [False],
                    [None]]
            self._prop_change_do("part state image setting", *args)
        elif prop == "border":
            args = [["image"], [prop], [value], ["image_border"], [False],
                    [None]]
            self._prop_change_do("part state image border setting", *args)
        elif prop == "middle":
            args = [["image"], [prop], [value], ["image_border_fill"], [False],
                    [None]]
            self._prop_change_do("part state \"middle\" setting", *args)

    def _prop_external_value_changed(self, prop, value):
        for p in self._params_info:
            if p.name == prop:
                if not p.validate(value):
                    nil, old_value = self.state.external_param_get(prop)
                    self["external"][prop].value = old_value
                    return
        args = [["external"], [prop], [value], [None], [True], [None]]
        self._prop_change_do(
            "(external) part state \"%s\" setting" % prop, *args)

    def _size_changed(self, obj):
        self["main"]["current"].value = obj.size
        if self.part_edje.type == edje.EDJE_PART_TYPE_IMAGE:
            obj.fill_set(0, 0, *obj.size)
Exemplo n.º 14
0
class PartAnimStateDetails(PartStateDetails):
    def __init__(
        self, parent, operation_stack_cb, img_new_img_cb=None,
        img_list_get_cb=None, img_id_get_cb=None, fnt_new_fnt_cb=None,
        fnt_list_get_cb=None, workfile_name_get_cb=None,
        part_object_get_cb=None, group="editje/collapsable/part_properties"):
        PartStateDetails.__init__(
            self, parent, operation_stack_cb, img_new_img_cb, img_list_get_cb,
            img_id_get_cb, fnt_new_fnt_cb, fnt_list_get_cb,
            workfile_name_get_cb, part_object_get_cb, group)

    def _context_recall(self, **kargs):
        self.e.animation.name = kargs["animation"]
        self.e.animation.state = kargs["time"]
        self.e.part.name = kargs["part"]
        self.e.part.state.name = kargs["state"]

    def _header_init(self, parent):
        self.title = "part frame properties"

        self._header_table = PropertyTable(parent, "part name/type")
        self.content_set("part_state.swallow", self._header_table)

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "type")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        prop.widget_add("t", wid)
        self._header_table.property_add(prop)

        self._source_prop = Property(parent, "source widget")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        self._source_prop.widget_add("s", wid)
        self._header_table.property_add(self._source_prop)
        self._source_prop.hide()

        self._module_prop = Property(parent, "module")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        self._module_prop.widget_add("m", wid)
        self._header_table.property_add(self._module_prop)
        self._module_prop.hide()

        self.content_set("part_name.swallow", self._header_table)
        self.e.animation.callback_add("animation.changed", self._anim_selected)
        self.e.animation.callback_add("animation.unselected",
                                      self._anim_unselected)
        self.e.animation.callback_add("part.added", self._anim_parts_changed)
        self.e.animation.callback_add("part.removed", self._anim_parts_changed)

        self._state_copy_button = StateCopyButton(self.e)

        self.edje_get().signal_callback_add(
            "cl,option,clicked", "editje/collapsable",
            self._state_copy_button._floater_open)

    def _show(self):
        state = self.part_edje.state_selected_get()
        self._header_table["name"].value = self.part_edje.name
        self._header_table["name"].show_value()
        self._header_table["type"].value = \
            part_type_to_text(self.part_edje.type)
        self._header_table["type"].show_value()

        if self.e.part.type == edje.EDJE_PART_TYPE_EXTERNAL:
            source = self.e.part.source
            if source.startswith("elm/"):
                source = source[4:]
                module = "Elementary"
            else:
                module = "Emotion"

            self.edje_get().signal_emit("cl,extra,activate", "")
            if "source widget" not in self._header_table:
                self._header_table.property_add(self._source_prop)
            if "module" not in self._header_table:
                self._header_table.property_add(self._module_prop)

            self._header_table["source widget"].value = source
            self._header_table["source widget"].show_value()
            self._header_table["module"].value = module
            self._header_table["module"].show_value()
        else:
            self._header_extra_hide()

        self.edje_get().signal_emit("cl,option,enable", "editje")
        self.state = self.part_edje.state_get(*state)
        self._update()
        self.show()

    def _header_extra_hide(self):
        self.edje_get().signal_emit("cl,extra,deactivate", "")
        for p in ["source widget", "module"]:
            if p in self._header_table:
                self._header_table.property_del(p)

    def _hide(self):
        self._header_table["name"].value = None
        self._header_table["name"].hide_value()
        self._header_table["type"].value = None
        self._header_table["type"].hide_value()
        self._header_extra_hide()

        self.edje_get().signal_emit("cl,option,disable", "editje")
        self._hide_all()
        self.hide()

    def _check_and_show(self):
        anim = self.e.animation
        part = self.e.part
        ret = anim.name and anim.part_belongs(part.name)
        if ret:
            self._show()
        else:
            self._hide()
        return ret

    def _part_update(self, emissor, data):
        if self.part_evas:
            self.part_evas.on_resize_del(self._size_changed)
        self.part_edje = self.e.part._part
        self.part_evas = self._part_object_get_cb(self.part_edje.name)
        self.part_evas.on_resize_add(self._size_changed)
        self._size_changed(self.part_evas)

        self._check_and_show()

    def _part_unselected(self, emissor, data):
        if self.part_evas:
            self.part_evas.on_resize_del(self._size_changed)

        self.part_evas = None
        self.part_edje = None
        self._hide()

    def _anim_selected(self, emissor, data):
        self._check_and_show()

    def _anim_unselected(self, emissor, data):
        self._hide()

    def _anim_parts_changed(self, emissor, data):
        self._check_and_show()

    def _state_changed_cb(self, emissor, data):
        if not data:
            return
        self.part_edje.state_selected_set(*data)
        self.state = self.e.part.state._state
        if self._check_and_show():
            self._update()
Exemplo n.º 15
0
class SignalDetails(EditjeDetails):
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(self,
                               parent,
                               operation_stack_cb,
                               group="editje/collapsable/part_state")

        self.title = "signal"

        self._parent = parent
        self._actions_added = 0

        self._header_table = PropertyTable(parent, "signal name",
                                           self._header_prop_value_changed)
        self.content_set("part_state.swallow", self._header_table)
        self.focus_custom_chain_set([self._header_table, self._box])

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Unique signal name.")
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        popup_hide_cb_list = [(self.e.signal, "program.unselected"),
                              (self.e.signal, "program.changed")]

        prop = Property(parent, "signal")
        wid = WidgetSignal(self,
                           popup_hide_object_signal_list=popup_hide_cb_list)
        wid.tooltip_set(
            "Signal to be received.", "Click to select one common"
            "<br>signal to be received.")
        prop.widget_add("s", wid)
        self["main"].property_add(prop)

        def parts_get():
            return self.e.parts

        def animations_get():
            return self.e.animations

        self._prop_source_animations = Property(parent, "source")
        wid = WidgetSource(self, "Animation list", animations_get,
                           popup_hide_cb_list)
        wid.tooltip_set(
            "Accepted signal source.", "Click to select one "
            "existent<br>animation as source.")
        self._prop_source_animations.widget_add("s", wid)
        self["main"].property_add(self._prop_source_animations)
        self["main"].property_del("source")

        self._prop_source_parts = Property(parent, "source")
        wid = WidgetSource(self, "Parts list", parts_get, popup_hide_cb_list)
        wid.tooltip_set("Accepted signal source.", "Click to select one "
                        "existent<br>part as source.")
        self._prop_source_parts.widget_add("s", wid)
        self["main"].property_add(self._prop_source_parts)

        prop = Property(parent, "delay")
        wid = WidgetEntry(self)
        wid.parser_in = lambda x: str(x)
        wid.parser_out = lambda x: float(x)
        wid.tooltip_set(
            "Fixed delay to do the action in seconds. The<br>total "
            "delay is sum off fixed and variable delays.")
        prop.widget_add("delay", wid)
        wid = WidgetEntry(self)
        wid.parser_in = lambda x: str(x)
        wid.parser_out = lambda x: float(x)
        wid.tooltip_set(
            "Variable delay to do the action in seconds. Will<br>be"
            " selected one random value between 0 and this.")
        prop.widget_add("range", wid)
        self["main"].property_add(prop)

        self.group_add("api")
        prop = Property(parent, "export")
        wid = WidgetBoolean(self)
        wid.tooltip_set("Add this part to exported signals.")
        prop.widget_add("export", wid)
        self["api"].property_add(prop)
        self._prop_api_name = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Export name of signal.")
        self._prop_api_name.widget_add("name", wid)
        self["api"].property_add(self._prop_api_name)
        self._prop_api_description = Property(parent, "description")
        wid = WidgetEntry(self)
        wid.tooltip_set("Description of exported signal.")
        self._prop_api_description.widget_add("description", wid)
        self["api"].property_add(self._prop_api_description)

        self.group_add("actions")

        self.group_add("out")

        prop = Property(parent, "signal")
        wid = WidgetSignal(self,
                           popup_hide_object_signal_list=popup_hide_cb_list)
        wid.tooltip_set("Signal to be emmited.", "Click to select one common "
                        "signal to be emmited.")
        prop.widget_add("s", wid)
        self["out"].property_add(prop)

        prop = Property(parent, "source")
        wid = WidgetSource(self, "Parts list", parts_get, popup_hide_cb_list)
        wid.tooltip_set("Name registered as signal source.", "Click to select "
                        "one existent<br>part as source.")
        prop.widget_add("s", wid)
        self["out"].property_add(prop)

        self.e.callback_add("signal.added", self._update)
        self.e.callback_add("signal.removed", self._removed)
        self.e.callback_add("group.changed", self._removed)
        self.e.signal.callback_add("program.changed", self._update)
        self.e.signal.callback_add("program.name.changed", self._update)
        self.e.signal.callback_add("program.unselected", self._removed)

        self.open = True
        self.open_disable = True
        self.show()
        self.__notification = None

    def _header_prop_value_changed(self, prop_name, prop_value, group_name):
        def signal_rename(old_name, new_name):
            # select 1st
            self._context_recall(signal=old_name)

            # rename later
            return self.e.signal.rename(new_name)

        if prop_name != "name":
            return

        old_name = self.e.signal.name
        if signal_rename(old_name, prop_value):
            op = Operation("signal renaming")

            op.redo_callback_add(signal_rename, old_name, prop_value)
            op.undo_callback_add(signal_rename, prop_value, old_name)
            self._operation_stack_cb(op)
        else:
            # TODO: notify the user of renaming failure
            self._header_table["name"].value = old_name

    def _new_action(self, number):
        def programs_get():
            return self.e.programs

        popup_hide_cb_list = [(self.e.signal, "program.unselected"),
                              (self.e.signal, "program.changed")]

        prop = Property(self._parent, "action " + str(number))
        wid = WidgetActionsList(self, "Animations", programs_get, None,
                                popup_hide_cb_list)
        wid.tooltip_set("Animation to be started.<br>Click to select it.")
        prop.widget_add("a", wid)
        self["actions"].property_add(prop)

    def _removed(self, emissor, data):
        self._header_table["name"].value = "Unselected"
        self._header_table["name"].value_obj._values_dict["n"].disabled_set(
            True)

        self["main"]["signal"].value = ""
        self["main"]["signal"].hide_value()

        self["main"]["source"].value = ""
        self["main"]["source"].hide_value()

        self["main"]["delay"].value = (None, None)
        self["main"]["delay"].hide_value()

        self.group_hide("api")
        self.group_show("api")

        if "name" in self["api"]:
            self["api"]["name"].value = None
            self["api"]["description"].value = None

        self.group_hide("actions")
        self.group_show("actions")

        for i in range(self._actions_added):
            self["actions"]["action " + str(i + 1)].value = ""
            self["actions"]["action " + str(i + 1)].hide_value()

        self.group_hide("out")
        self.group_show("out")

        self["out"]["signal"].value = ""
        self["out"]["signal"].hide_value()

        self["out"]["source"].value = ""
        self["out"]["source"].hide_value()

        self.open_set(False)

    def _update(self, emissor, data):
        self._emissor = emissor
        self._data = data

        self._header_table["name"].value = self.e.signal.name
        self._header_table["name"].show_value()
        self._header_table["name"].value_obj._values_dict["n"].disabled_set(
            False)

        signal = self.e.signal.signal
        self["main"]["signal"].show_value()
        if signal:
            self["main"]["signal"].value = signal
        else:
            self.e.signal.signal = ""
            self["main"]["signal"].value = ""

        source = self.e.signal.source
        self["main"]["source"].show_value()
        if source:
            self["main"]["source"].value = source
        else:
            self.e.signal.source = ""
            self["main"]["source"].value = ""

        self["main"]["delay"].show_value()
        self["main"]["delay"].value = self.e.signal.in_time

        action = self.e.signal.action

        self._update_api_props(self.e.signal.api_export, self.e.signal.api)
        self.group_hide("api")
        self.group_show("api")

        if action == edje.EDJE_ACTION_TYPE_NONE:
            afters = self.e.signal.afters

            while (self._actions_added < len(afters) + 1):
                self._actions_added = self._actions_added + 1
                self._new_action(self._actions_added)

            for i in range(self._actions_added):
                self["actions"]["action " + str(i + 1)].hide()

            for i in range(len(afters)):
                self["actions"]["action " + str(i + 1)].show_value()
                self["actions"]["action " + str(i + 1)].show()
                fixedname = re_anim_program.match(afters[i]).groups()[0]
                self["actions"]["action " + str(i + 1)].value = fixedname
            # The last action with none value
            self["actions"]["action " + str(len(afters) + 1)].show_value()
            self["actions"]["action " + str(len(afters) + 1)].show()
            self["actions"]["action " + str(len(afters) + 1)].value = ""

            self.group_hide("out")
            self.group_hide("actions")
            self.group_show("actions")

        elif action == edje.EDJE_ACTION_TYPE_SIGNAL_EMIT:
            self.group_hide("actions")
            self.group_hide("out")
            self.group_show("out")

            state = self.e.signal.state_get()
            self["out"]["signal"].show_value()
            if state:
                self["out"]["signal"].value = state
            else:
                self["out"]["signal"].value = ""

            state = self.e.signal._program.state2_get()
            self["out"]["source"].show_value()
            if state:
                self["out"]["source"].value = state
            else:
                self["out"]["source"].value = ""

        self.open_set(True)
        self.show()

    def _context_recall(self, **kargs):
        self.e.signal.name = kargs["signal"]

    def _prop_object_get(self):
        return self.e.signal

    def _notify(self, message):
        if self.__notification:
            self.__notification.hide()
            self.__notification.delete()
            self.__notification = None
        self.__notification = Notify(self._parent)
        self.__notification.timeout_set(4)
        self.__notification.orient_set(ELM_NOTIFY_ORIENT_BOTTOM)

        bx = Box(self)
        bx.size_hint_weight_set(evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND)
        bx.horizontal_set(True)
        self.__notification.content_set(bx)
        bx.show()

        lb = Label(self)
        lb.text_set(message)
        bx.pack_end(lb)
        lb.show()

        self.__notification.show()

    def _conflicting_animation_get(self, afters_list, anim):
        if not afters_list or not anim:
            return None
        anim_targets_list = self.e.edje.program_get(anim).targets_get()
        for after in afters_list:
            after_targets_list = self.e.edje.program_get(after).targets_get()
            for target in anim_targets_list:
                if target in after_targets_list:
                    return after
        return None

    def prop_value_changed(self, prop, value, group):
        if group == "main":
            if prop == "signal":
                args = [["main"], [prop], [value], [None], [False], [None]]
                self._prop_change_do("signal's triggering action change",
                                     *args)
                self["main"].property_del("source")
                if value == "animation,end":
                    self["main"].property_add(self._prop_source_animations, 1)
                else:
                    self["main"].property_add(self._prop_source_parts, 1)

            elif prop == "source":
                args = [["main"], [prop], [value], [None], [False], [None]]
                self._prop_change_do("signal's source part change", *args)

            elif prop == "delay":
                args = [["main"], [prop], [value], ["in_time"], [False],
                        [None]]
                self._prop_change_do("signal's source delay time change",
                                     *args)

        elif group == "actions":

            def afters_change(afters, sig_name):
                self._context_recall(signal=sig_name)

                self.e.signal.afters_clear()
                for i in range(len(afters)):
                    self.e.signal.after_add(afters[i])
                self._update(self._emissor, self._data)

            old_afters = self.e.signal._afters_get()
            new_afters = self.e.signal._afters_get()

            if value in old_afters:
                value = re_anim_program.match(value).groups()[0]
                self._notify("Error: " + value + " is already in the list")
                self._update(self._emissor, self._data)
                return

            action_number = int(re.match("action (\d+)", prop).group(1))

            if value:
                if action_number <= len(new_afters):
                    new_afters[action_number - 1] = value
                else:
                    new_afters.append(value)
            elif action_number <= len(new_afters):
                new_afters.pop(action_number - 1)

            conflicting_after = self._conflicting_animation_get(
                new_afters, value)
            if conflicting_after and conflicting_after != value:
                conflicting_after = re_anim_program.match(
                    conflicting_after).groups()[0]
                self._notify("Error: this animation conflicts with " +
                             conflicting_after + ".<br>"
                             "There are parts in common being animated.")
                self._update(self._emissor, self._data)
                return

            op = Operation("signal's \"after\" action change")
            op.redo_callback_add(afters_change, new_afters, self.e.signal.name)
            op.undo_callback_add(afters_change, old_afters, self.e.signal.name)
            self._operation_stack_cb(op)
            op.redo()

        elif group == "out":
            if prop == "signal":

                def signal_change(value, sig_name):
                    self._context_recall(signal=sig_name)

                    self.e.signal.signal_emit_action_set(value)
                    self["out"]["signal"].value = value[0]

                val = [value, self["out"]["source"].value]
                old_val = [self.e.signal.state_get() or "", val[1]]

                op = Operation("signal's \"out\" emission change")
                op.redo_callback_add(signal_change, val, self.e.signal.name)
                op.undo_callback_add(signal_change, old_val,
                                     self.e.signal.name)
                self._operation_stack_cb(op)
                op.redo()

            elif prop == "source":

                def source_change(value, sig_name):
                    self._context_recall(signal=sig_name)

                    self.e.signal.signal_emit_action_set(value)
                    self["out"]["source"].value = value[1]

                val = [self["out"]["signal"].value, value]
                old_val = [val[0], self.e.signal.state2_get() or ""]

                op = Operation("signal's \"out\" source change")
                op.redo_callback_add(source_change, val, self.e.signal.name)
                op.undo_callback_add(source_change, old_val,
                                     self.e.signal.name)
                self._operation_stack_cb(op)
                op.redo()

        elif group == "api":
            if prop == "name":

                def api_name_change(value, sig_name):
                    self._context_recall(signal=sig_name)
                    self.e.signal.api = value
                    self["api"]["name"].value = value[0]

                val = [value, self.e.signal.api[1]]
                old_val = [self.e.signal.api[0], val[1]]

                op = Operation("program's api name change")
                op.redo_callback_add(api_name_change, val, self.e.signal.name)
                op.undo_callback_add(api_name_change, old_val,
                                     self.e.signal.name)
                self._operation_stack_cb(op)
                op.redo()

            if prop == "description":

                def api_description_change(value, sig_name):
                    self._context_recall(signal=sig_name)
                    self.e.signal.api = value
                    self["api"]["description"].value = value[1]

                val = [self.e.signal.api[0], value]
                old_val = [val[0], self.e.signal.api[1]]

                op = Operation("program's api description change")
                op.redo_callback_add(api_description_change, val,
                                     self.e.signal.name)
                op.undo_callback_add(api_description_change, old_val,
                                     self.e.signal.name)
                self._operation_stack_cb(op)
                op.redo()

            if prop == "export":

                def api_export_change(value, sig_name, export):
                    self._context_recall(signal=sig_name)
                    self.e.signal.api_export = export
                    self.e.signal.api = value
                    self._update_api_props(export, value)

                export = value
                old_export = self.e.signal.api_export
                old_val = [self.e.signal.api[0], self.e.signal.api[1]]
                val = [None, None]

                op = Operation("program's api description change")
                op.redo_callback_add(api_export_change, val,
                                     self.e.signal.name, export)
                op.undo_callback_add(api_export_change, old_val,
                                     self.e.signal.name, old_export)
                self._operation_stack_cb(op)
                op.redo()

    def _update_api_props(self, export, api):
        self["api"]["export"].value = export
        if self["api"]["export"].value:
            if "name" not in self["api"]:
                self["api"].property_add(self._prop_api_name)
                self["api"].property_add(self._prop_api_description)
            self["api"]["name"].value = api[0]
            self["api"]["description"].value = api[1]
        elif "name" in self["api"]:
            self["api"].property_del("name")
            self["api"].property_del("description")
Exemplo n.º 16
0
class AnimationDetails(EditjeDetails):
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(
            self, parent, operation_stack_cb,
            group="editje/collapsable/part_properties")

        self.title = "animation"

        self._transitions = ['None', 'Linear', 'Sinusoidal', 'Accelerate',
                             'Decelerate']

        self._header_table = PropertyTable(
            parent, "animation name", self.header_prop_value_changed)
        self.content_set("part_name.swallow", self._header_table)
        self.focus_custom_chain_set([self._header_table, self._box])

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Unique animation name.")
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "length")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Time lenght of animation<br>in seconds.")
        prop.widget_add("l", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "current")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of current keyframe<br>in seconds.")
        prop.widget_add("c", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "previous")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of previous keyframe<br>in seconds.")
        prop.widget_add("p", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "next")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of next keyframe<br>in seconds.")
        prop.widget_add("n", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "transition")
        wid = WidgetCombo(parent)
        for null, i in enumerate(self._transitions):
            wid.item_add(i)
        wid.tooltip_set("Transition effect to interpolation<br>"
                        "between the previous keyframe<br>and this.")
        prop.widget_add("type", wid)
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Transition time between the<br>"
                        "previous keyframe and this,<br>in seconds.")
        prop.widget_add("length", wid)
        self["main"].property_add(prop)

        self._parent.main_edje.signal_callback_add("timestop", "*",
                                                   self._timeline_cb)
        self._parent.main_edje.signal_callback_add("timeremove", "*",
                                                   self._timeremove_cb)
        self.e.callback_add("animation.removed", self._removed)
        self.e.animation.callback_add("animation.changed", self._update)
        self.e.animation.callback_add("animation.unselected", self._removed)
        self.e.animation.callback_add("state.added", self._timestop_add)
        self.e.animation.callback_add("frame.changed", self._update_states)

    def _removed(self, emissor, data):
        self.open_disable = True
        self._header_table["name"].value = "Unselected"
        self._header_table["name"].value_obj._values_dict["n"].disabled_set(
            True)
        self._header_table["length"].value = None
        self["main"]["current"].hide_value()
        self["main"]["previous"].hide_value()
        self["main"]["next"].hide_value()
        self["main"]["transition"].hide_value()
        self["main"]["transition"].value_obj._values_dict["type"].hover_end()
        self._timeline_clear()
        self._parent.main_edje.signal_emit("timeline,block", "")
        self.open = False
        self.open_disable = True

    def _update(self, emissor, data):
        self.open_disable = False
        self._header_table["name"].value = data
        self._header_table["name"].value_obj._values_dict["n"].disabled_set(
            False)
        self._header_table["length"].value = "%.1gs" % self.e.animation.length
        self._last_timestamp = 0.0
        self._timeline_update()
        self._parent.main_edje.signal_emit("timeline,unblock", "")

        self.open_disable = False
        self.open = True
        self.show()

    def _timeline_cb(self, obj, emission, source):
        t = float(source)
        if not t in self.e.animation.timestops:
            anim_name = self.e.animation.name
            anim_frame = self.e.animation.state
            self.e.animation.state_add(t)
            op = Operation("animation (%s) frame (%s) creation" % \
                               (self.e.animation.name, t))
            op.redo_callback_add(self._state_add, t, anim_name)
            op.redo_callback_add(setattr, self.e.animation, "state", t)
            op.undo_callback_add(self._remove_time_point,
                                 t, anim_name, anim_frame)
            self._operation_stack_cb(op)

        self.e.animation.state = t

    def _state_add(self, t, anim_name):
        self._context_recall(animation=anim_name)
        self.e.animation.state_add(t)

    def _remove_time_point(self, t, anim_name, anim_frame):
        self._context_recall(animation=anim_name, time=anim_frame)
        prog = "@%s@%.2f" % (self.e.animation.name, t)
        self.e.animation.state_prev_goto()
        self.e.animation.state_del(t)
        self.e.program_del(prog)
        self._parent.main_edje.signal_emit("ts,%.1g,disable" % t, "editje")
        self._parent.main_edje.signal_emit("ts,%.1g,unselected" % t, "editje")

    def _frame_readd(self, t, anim_name, saved_states, trans):
        self.e.animation.name = anim_name
        self.e.animation.state_add(t)
        for pname, state in saved_states:
            self.e.part.name = pname
            st = self.e.part_get(pname).state_get(state.name)
            state.apply_to(st)
        self.e.animation.state = t
        self.e.animation.program.transition = trans
        self.e.animation.event_emit("frame.changed")

    def _timeremove_cb(self, obj, emission, source):
        t = float(source)
        anim_name = self.e.animation.name
        anim_frame = self.e.animation.state
        prog = "@%s@%.2f" % (anim_name, t)

        saved_states = []
        for part_name in self.e.animation.parts:
            part = self.e.part_get(part_name)
            st_obj = part.state_get(prog)
            st_class = objects_data.state_class_from_part_type_get(part)
            state_save = st_class(st_obj)
            saved_states.append([part.name, state_save])

        trans = self.e.animation.program.transition

        def agree(bt, notification):
            self._remove_time_point(t, anim_name, anim_frame)
            notification.hide()
            notification.delete()
            op = Operation("animation (%s) frame (%s) deletion" % \
                               (anim_name, t))
            op.redo_callback_add(self._remove_time_point, t, anim_name,
                                 anim_frame)
            op.undo_callback_add(
                self._frame_readd, t, anim_name, saved_states, trans)
            self._operation_stack_cb(op)

        def disagree(bt, notification):
            notification.hide()
            notification.delete()

        if t in self.e.animation.timestops:
            notification = ErrorNotify(
                self._parent, orient=elementary.ELM_NOTIFY_ORIENT_CENTER)
            notification.title = "Do you really want to delete this " \
                "animation frame?"
            notification.action_add("Yes", agree, None, notification)
            notification.action_add("No", disagree, None,  notification)
            notification.show()

    def _timeline_clear(self):
        for i in range(0, 11):
            sig = "ts,%.1g," % (i / 10.0)
            self._parent.main_edje.signal_emit(sig + "disable", "editje")
            self._parent.main_edje.signal_emit(sig + "unselected", "editje")

    def _timeline_update(self):
        self._timeline_clear()
        for s in self.e.animation.timestops:
            sig = "ts,%.1g,enable" % s
            self._parent.main_edje.signal_emit(sig, "editje")

    def _timestop_add(self, emissor, data):
        self._parent.main_edje.signal_emit("ts,%.1g,enable" % data, "editje")
        self._header_table["length"].value = "%.1gs" % self.e.animation.length

    def _update_states(self, emissor, data):
        step = self.e.animation.state
        self["main"]["current"].show_value()
        self["main"]["current"].value = str(step)

        prev = self.e.animation.state_prev()
        self["main"]["previous"].show_value()
        if prev is None:
            prev = 0.0
            self["main"]["previous"].value = "None"
        else:
            self["main"]["previous"].value = str(prev)

        next_state = self.e.animation.state_next()
        self["main"]["next"].show_value()
        if next_state is None:
            self["main"]["next"].value = "None"
        else:
            self["main"]["next"].value = str(next_state)

        t = self._transitions[self.e.animation.program.transition]
        self["main"]["transition"].show_value()
        self["main"]["transition"].value = (t, str(step - prev))

        sig = "ts,%.1g,selected" % self.e.animation.state
        self._parent.main_edje.signal_emit(sig, "editje")
        if self.e.animation.state != 0.0:
            sig = "ts,rm,%.1g,selected" % self.e.animation.state
            self._parent.main_edje.signal_emit(sig, "editje")
        sig = "ts,%.1g,unselected" % self._last_timestamp
        if self._last_timestamp != self.e.animation.state:
            self._parent.main_edje.signal_emit(sig, "editje")
            sig = "ts,rm,%.1g,unselected" % self._last_timestamp
            self._parent.main_edje.signal_emit(sig, "editje")
        self._last_timestamp = self.e.animation.state

    def header_prop_value_changed(self, prop, value, group):
        if prop == "name":
            if not self.e.animation.name_set(value):
                self._header_table["name"].value = self.e.animation.name

    def _context_recall(self, **kargs):
        if "animation" in kargs:
            self.e.animation.name = kargs["animation"]
            if "time" in kargs:
                self.e.animation.state = kargs["time"]
        if "part" in kargs:
            self.e.part.name = kargs["part"]
            if "state" in kargs:
                self.e.part.state.name = kargs["state"]

    def _prop_object_get(self):
        return self.e.animation.program

    def prop_value_changed(self, prop, value, group):
        if prop == "transition":
            args = [["main"], [prop], [self._transitions.index(value[0])],
                    [None], [False],
                    [lambda x: (self._transitions[x], value[1])]]

            self._prop_change_do("animation state transition", *args)
Exemplo n.º 17
0
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(self, parent, operation_stack_cb, group="editje/collapsable/part_state")

        self.title = "signal"

        self._parent = parent
        self._actions_added = 0

        self._header_table = PropertyTable(parent, "signal name", self._header_prop_value_changed)
        self.content_set("part_state.swallow", self._header_table)
        self.focus_custom_chain_set([self._header_table, self._box])

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Unique signal name.")
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        popup_hide_cb_list = [(self.e.signal, "program.unselected"), (self.e.signal, "program.changed")]

        prop = Property(parent, "signal")
        wid = WidgetSignal(self, popup_hide_object_signal_list=popup_hide_cb_list)
        wid.tooltip_set("Signal to be received.", "Click to select one common" "<br>signal to be received.")
        prop.widget_add("s", wid)
        self["main"].property_add(prop)

        def parts_get():
            return self.e.parts

        def animations_get():
            return self.e.animations

        self._prop_source_animations = Property(parent, "source")
        wid = WidgetSource(self, "Animation list", animations_get, popup_hide_cb_list)
        wid.tooltip_set("Accepted signal source.", "Click to select one " "existent<br>animation as source.")
        self._prop_source_animations.widget_add("s", wid)
        self["main"].property_add(self._prop_source_animations)
        self["main"].property_del("source")

        self._prop_source_parts = Property(parent, "source")
        wid = WidgetSource(self, "Parts list", parts_get, popup_hide_cb_list)
        wid.tooltip_set("Accepted signal source.", "Click to select one " "existent<br>part as source.")
        self._prop_source_parts.widget_add("s", wid)
        self["main"].property_add(self._prop_source_parts)

        prop = Property(parent, "delay")
        wid = WidgetEntry(self)
        wid.parser_in = lambda x: str(x)
        wid.parser_out = lambda x: float(x)
        wid.tooltip_set(
            "Fixed delay to do the action in seconds. The<br>total " "delay is sum off fixed and variable delays."
        )
        prop.widget_add("delay", wid)
        wid = WidgetEntry(self)
        wid.parser_in = lambda x: str(x)
        wid.parser_out = lambda x: float(x)
        wid.tooltip_set(
            "Variable delay to do the action in seconds. Will<br>be" " selected one random value between 0 and this."
        )
        prop.widget_add("range", wid)
        self["main"].property_add(prop)

        self.group_add("api")
        prop = Property(parent, "export")
        wid = WidgetBoolean(self)
        wid.tooltip_set("Add this part to exported signals.")
        prop.widget_add("export", wid)
        self["api"].property_add(prop)
        self._prop_api_name = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Export name of signal.")
        self._prop_api_name.widget_add("name", wid)
        self["api"].property_add(self._prop_api_name)
        self._prop_api_description = Property(parent, "description")
        wid = WidgetEntry(self)
        wid.tooltip_set("Description of exported signal.")
        self._prop_api_description.widget_add("description", wid)
        self["api"].property_add(self._prop_api_description)

        self.group_add("actions")

        self.group_add("out")

        prop = Property(parent, "signal")
        wid = WidgetSignal(self, popup_hide_object_signal_list=popup_hide_cb_list)
        wid.tooltip_set("Signal to be emmited.", "Click to select one common " "signal to be emmited.")
        prop.widget_add("s", wid)
        self["out"].property_add(prop)

        prop = Property(parent, "source")
        wid = WidgetSource(self, "Parts list", parts_get, popup_hide_cb_list)
        wid.tooltip_set("Name registered as signal source.", "Click to select " "one existent<br>part as source.")
        prop.widget_add("s", wid)
        self["out"].property_add(prop)

        self.e.callback_add("signal.added", self._update)
        self.e.callback_add("signal.removed", self._removed)
        self.e.callback_add("group.changed", self._removed)
        self.e.signal.callback_add("program.changed", self._update)
        self.e.signal.callback_add("program.name.changed", self._update)
        self.e.signal.callback_add("program.unselected", self._removed)

        self.open = True
        self.open_disable = True
        self.show()
        self.__notification = None
Exemplo n.º 18
0
class SignalDetails(EditjeDetails):
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(self, parent, operation_stack_cb, group="editje/collapsable/part_state")

        self.title = "signal"

        self._parent = parent
        self._actions_added = 0

        self._header_table = PropertyTable(parent, "signal name", self._header_prop_value_changed)
        self.content_set("part_state.swallow", self._header_table)
        self.focus_custom_chain_set([self._header_table, self._box])

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Unique signal name.")
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        popup_hide_cb_list = [(self.e.signal, "program.unselected"), (self.e.signal, "program.changed")]

        prop = Property(parent, "signal")
        wid = WidgetSignal(self, popup_hide_object_signal_list=popup_hide_cb_list)
        wid.tooltip_set("Signal to be received.", "Click to select one common" "<br>signal to be received.")
        prop.widget_add("s", wid)
        self["main"].property_add(prop)

        def parts_get():
            return self.e.parts

        def animations_get():
            return self.e.animations

        self._prop_source_animations = Property(parent, "source")
        wid = WidgetSource(self, "Animation list", animations_get, popup_hide_cb_list)
        wid.tooltip_set("Accepted signal source.", "Click to select one " "existent<br>animation as source.")
        self._prop_source_animations.widget_add("s", wid)
        self["main"].property_add(self._prop_source_animations)
        self["main"].property_del("source")

        self._prop_source_parts = Property(parent, "source")
        wid = WidgetSource(self, "Parts list", parts_get, popup_hide_cb_list)
        wid.tooltip_set("Accepted signal source.", "Click to select one " "existent<br>part as source.")
        self._prop_source_parts.widget_add("s", wid)
        self["main"].property_add(self._prop_source_parts)

        prop = Property(parent, "delay")
        wid = WidgetEntry(self)
        wid.parser_in = lambda x: str(x)
        wid.parser_out = lambda x: float(x)
        wid.tooltip_set(
            "Fixed delay to do the action in seconds. The<br>total " "delay is sum off fixed and variable delays."
        )
        prop.widget_add("delay", wid)
        wid = WidgetEntry(self)
        wid.parser_in = lambda x: str(x)
        wid.parser_out = lambda x: float(x)
        wid.tooltip_set(
            "Variable delay to do the action in seconds. Will<br>be" " selected one random value between 0 and this."
        )
        prop.widget_add("range", wid)
        self["main"].property_add(prop)

        self.group_add("api")
        prop = Property(parent, "export")
        wid = WidgetBoolean(self)
        wid.tooltip_set("Add this part to exported signals.")
        prop.widget_add("export", wid)
        self["api"].property_add(prop)
        self._prop_api_name = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Export name of signal.")
        self._prop_api_name.widget_add("name", wid)
        self["api"].property_add(self._prop_api_name)
        self._prop_api_description = Property(parent, "description")
        wid = WidgetEntry(self)
        wid.tooltip_set("Description of exported signal.")
        self._prop_api_description.widget_add("description", wid)
        self["api"].property_add(self._prop_api_description)

        self.group_add("actions")

        self.group_add("out")

        prop = Property(parent, "signal")
        wid = WidgetSignal(self, popup_hide_object_signal_list=popup_hide_cb_list)
        wid.tooltip_set("Signal to be emmited.", "Click to select one common " "signal to be emmited.")
        prop.widget_add("s", wid)
        self["out"].property_add(prop)

        prop = Property(parent, "source")
        wid = WidgetSource(self, "Parts list", parts_get, popup_hide_cb_list)
        wid.tooltip_set("Name registered as signal source.", "Click to select " "one existent<br>part as source.")
        prop.widget_add("s", wid)
        self["out"].property_add(prop)

        self.e.callback_add("signal.added", self._update)
        self.e.callback_add("signal.removed", self._removed)
        self.e.callback_add("group.changed", self._removed)
        self.e.signal.callback_add("program.changed", self._update)
        self.e.signal.callback_add("program.name.changed", self._update)
        self.e.signal.callback_add("program.unselected", self._removed)

        self.open = True
        self.open_disable = True
        self.show()
        self.__notification = None

    def _header_prop_value_changed(self, prop_name, prop_value, group_name):
        def signal_rename(old_name, new_name):
            # select 1st
            self._context_recall(signal=old_name)

            # rename later
            return self.e.signal.rename(new_name)

        if prop_name != "name":
            return

        old_name = self.e.signal.name
        if signal_rename(old_name, prop_value):
            op = Operation("signal renaming")

            op.redo_callback_add(signal_rename, old_name, prop_value)
            op.undo_callback_add(signal_rename, prop_value, old_name)
            self._operation_stack_cb(op)
        else:
            # TODO: notify the user of renaming failure
            self._header_table["name"].value = old_name

    def _new_action(self, number):
        def programs_get():
            return self.e.programs

        popup_hide_cb_list = [(self.e.signal, "program.unselected"), (self.e.signal, "program.changed")]

        prop = Property(self._parent, "action " + str(number))
        wid = WidgetActionsList(self, "Animations", programs_get, None, popup_hide_cb_list)
        wid.tooltip_set("Animation to be started.<br>Click to select it.")
        prop.widget_add("a", wid)
        self["actions"].property_add(prop)

    def _removed(self, emissor, data):
        self._header_table["name"].value = "Unselected"
        self._header_table["name"].value_obj._values_dict["n"].disabled_set(True)

        self["main"]["signal"].value = ""
        self["main"]["signal"].hide_value()

        self["main"]["source"].value = ""
        self["main"]["source"].hide_value()

        self["main"]["delay"].value = (None, None)
        self["main"]["delay"].hide_value()

        self.group_hide("api")
        self.group_show("api")

        if "name" in self["api"]:
            self["api"]["name"].value = None
            self["api"]["description"].value = None

        self.group_hide("actions")
        self.group_show("actions")

        for i in range(self._actions_added):
            self["actions"]["action " + str(i + 1)].value = ""
            self["actions"]["action " + str(i + 1)].hide_value()

        self.group_hide("out")
        self.group_show("out")

        self["out"]["signal"].value = ""
        self["out"]["signal"].hide_value()

        self["out"]["source"].value = ""
        self["out"]["source"].hide_value()

        self.open_set(False)

    def _update(self, emissor, data):
        self._emissor = emissor
        self._data = data

        self._header_table["name"].value = self.e.signal.name
        self._header_table["name"].show_value()
        self._header_table["name"].value_obj._values_dict["n"].disabled_set(False)

        signal = self.e.signal.signal
        self["main"]["signal"].show_value()
        if signal:
            self["main"]["signal"].value = signal
        else:
            self.e.signal.signal = ""
            self["main"]["signal"].value = ""

        source = self.e.signal.source
        self["main"]["source"].show_value()
        if source:
            self["main"]["source"].value = source
        else:
            self.e.signal.source = ""
            self["main"]["source"].value = ""

        self["main"]["delay"].show_value()
        self["main"]["delay"].value = self.e.signal.in_time

        action = self.e.signal.action

        self._update_api_props(self.e.signal.api_export, self.e.signal.api)
        self.group_hide("api")
        self.group_show("api")

        if action == edje.EDJE_ACTION_TYPE_NONE:
            afters = self.e.signal.afters

            while self._actions_added < len(afters) + 1:
                self._actions_added = self._actions_added + 1
                self._new_action(self._actions_added)

            for i in range(self._actions_added):
                self["actions"]["action " + str(i + 1)].hide()

            for i in range(len(afters)):
                self["actions"]["action " + str(i + 1)].show_value()
                self["actions"]["action " + str(i + 1)].show()
                fixedname = re_anim_program.match(afters[i]).groups()[0]
                self["actions"]["action " + str(i + 1)].value = fixedname
            # The last action with none value
            self["actions"]["action " + str(len(afters) + 1)].show_value()
            self["actions"]["action " + str(len(afters) + 1)].show()
            self["actions"]["action " + str(len(afters) + 1)].value = ""

            self.group_hide("out")
            self.group_hide("actions")
            self.group_show("actions")

        elif action == edje.EDJE_ACTION_TYPE_SIGNAL_EMIT:
            self.group_hide("actions")
            self.group_hide("out")
            self.group_show("out")

            state = self.e.signal.state_get()
            self["out"]["signal"].show_value()
            if state:
                self["out"]["signal"].value = state
            else:
                self["out"]["signal"].value = ""

            state = self.e.signal._program.state2_get()
            self["out"]["source"].show_value()
            if state:
                self["out"]["source"].value = state
            else:
                self["out"]["source"].value = ""

        self.open_set(True)
        self.show()

    def _context_recall(self, **kargs):
        self.e.signal.name = kargs["signal"]

    def _prop_object_get(self):
        return self.e.signal

    def _notify(self, message):
        if self.__notification:
            self.__notification.hide()
            self.__notification.delete()
            self.__notification = None
        self.__notification = Notify(self._parent)
        self.__notification.timeout_set(4)
        self.__notification.orient_set(ELM_NOTIFY_ORIENT_BOTTOM)

        bx = Box(self)
        bx.size_hint_weight_set(evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND)
        bx.horizontal_set(True)
        self.__notification.content_set(bx)
        bx.show()

        lb = Label(self)
        lb.text_set(message)
        bx.pack_end(lb)
        lb.show()

        self.__notification.show()

    def _conflicting_animation_get(self, afters_list, anim):
        if not afters_list or not anim:
            return None
        anim_targets_list = self.e.edje.program_get(anim).targets_get()
        for after in afters_list:
            after_targets_list = self.e.edje.program_get(after).targets_get()
            for target in anim_targets_list:
                if target in after_targets_list:
                    return after
        return None

    def prop_value_changed(self, prop, value, group):
        if group == "main":
            if prop == "signal":
                args = [["main"], [prop], [value], [None], [False], [None]]
                self._prop_change_do("signal's triggering action change", *args)
                self["main"].property_del("source")
                if value == "animation,end":
                    self["main"].property_add(self._prop_source_animations, 1)
                else:
                    self["main"].property_add(self._prop_source_parts, 1)

            elif prop == "source":
                args = [["main"], [prop], [value], [None], [False], [None]]
                self._prop_change_do("signal's source part change", *args)

            elif prop == "delay":
                args = [["main"], [prop], [value], ["in_time"], [False], [None]]
                self._prop_change_do("signal's source delay time change", *args)

        elif group == "actions":

            def afters_change(afters, sig_name):
                self._context_recall(signal=sig_name)

                self.e.signal.afters_clear()
                for i in range(len(afters)):
                    self.e.signal.after_add(afters[i])
                self._update(self._emissor, self._data)

            old_afters = self.e.signal._afters_get()
            new_afters = self.e.signal._afters_get()

            if value in old_afters:
                value = re_anim_program.match(value).groups()[0]
                self._notify("Error: " + value + " is already in the list")
                self._update(self._emissor, self._data)
                return

            action_number = int(re.match("action (\d+)", prop).group(1))

            if value:
                if action_number <= len(new_afters):
                    new_afters[action_number - 1] = value
                else:
                    new_afters.append(value)
            elif action_number <= len(new_afters):
                new_afters.pop(action_number - 1)

            conflicting_after = self._conflicting_animation_get(new_afters, value)
            if conflicting_after and conflicting_after != value:
                conflicting_after = re_anim_program.match(conflicting_after).groups()[0]
                self._notify(
                    "Error: this animation conflicts with " + conflicting_after + ".<br>"
                    "There are parts in common being animated."
                )
                self._update(self._emissor, self._data)
                return

            op = Operation('signal\'s "after" action change')
            op.redo_callback_add(afters_change, new_afters, self.e.signal.name)
            op.undo_callback_add(afters_change, old_afters, self.e.signal.name)
            self._operation_stack_cb(op)
            op.redo()

        elif group == "out":
            if prop == "signal":

                def signal_change(value, sig_name):
                    self._context_recall(signal=sig_name)

                    self.e.signal.signal_emit_action_set(value)
                    self["out"]["signal"].value = value[0]

                val = [value, self["out"]["source"].value]
                old_val = [self.e.signal.state_get() or "", val[1]]

                op = Operation('signal\'s "out" emission change')
                op.redo_callback_add(signal_change, val, self.e.signal.name)
                op.undo_callback_add(signal_change, old_val, self.e.signal.name)
                self._operation_stack_cb(op)
                op.redo()

            elif prop == "source":

                def source_change(value, sig_name):
                    self._context_recall(signal=sig_name)

                    self.e.signal.signal_emit_action_set(value)
                    self["out"]["source"].value = value[1]

                val = [self["out"]["signal"].value, value]
                old_val = [val[0], self.e.signal.state2_get() or ""]

                op = Operation('signal\'s "out" source change')
                op.redo_callback_add(source_change, val, self.e.signal.name)
                op.undo_callback_add(source_change, old_val, self.e.signal.name)
                self._operation_stack_cb(op)
                op.redo()

        elif group == "api":
            if prop == "name":

                def api_name_change(value, sig_name):
                    self._context_recall(signal=sig_name)
                    self.e.signal.api = value
                    self["api"]["name"].value = value[0]

                val = [value, self.e.signal.api[1]]
                old_val = [self.e.signal.api[0], val[1]]

                op = Operation("program's api name change")
                op.redo_callback_add(api_name_change, val, self.e.signal.name)
                op.undo_callback_add(api_name_change, old_val, self.e.signal.name)
                self._operation_stack_cb(op)
                op.redo()

            if prop == "description":

                def api_description_change(value, sig_name):
                    self._context_recall(signal=sig_name)
                    self.e.signal.api = value
                    self["api"]["description"].value = value[1]

                val = [self.e.signal.api[0], value]
                old_val = [val[0], self.e.signal.api[1]]

                op = Operation("program's api description change")
                op.redo_callback_add(api_description_change, val, self.e.signal.name)
                op.undo_callback_add(api_description_change, old_val, self.e.signal.name)
                self._operation_stack_cb(op)
                op.redo()

            if prop == "export":

                def api_export_change(value, sig_name, export):
                    self._context_recall(signal=sig_name)
                    self.e.signal.api_export = export
                    self.e.signal.api = value
                    self._update_api_props(export, value)

                export = value
                old_export = self.e.signal.api_export
                old_val = [self.e.signal.api[0], self.e.signal.api[1]]
                val = [None, None]

                op = Operation("program's api description change")
                op.redo_callback_add(api_export_change, val, self.e.signal.name, export)
                op.undo_callback_add(api_export_change, old_val, self.e.signal.name, old_export)
                self._operation_stack_cb(op)
                op.redo()

    def _update_api_props(self, export, api):
        self["api"]["export"].value = export
        if self["api"]["export"].value:
            if "name" not in self["api"]:
                self["api"].property_add(self._prop_api_name)
                self["api"].property_add(self._prop_api_description)
            self["api"]["name"].value = api[0]
            self["api"]["description"].value = api[1]
        elif "name" in self["api"]:
            self["api"].property_del("name")
            self["api"].property_del("description")
Exemplo n.º 19
0
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(
            self, parent, operation_stack_cb,
            group="editje/collapsable/part_properties")

        self.title = "animation"

        self._transitions = ['None', 'Linear', 'Sinusoidal', 'Accelerate',
                             'Decelerate']

        self._header_table = PropertyTable(
            parent, "animation name", self.header_prop_value_changed)
        self.content_set("part_name.swallow", self._header_table)
        self.focus_custom_chain_set([self._header_table, self._box])

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Unique animation name.")
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "length")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Time lenght of animation<br>in seconds.")
        prop.widget_add("l", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "current")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of current keyframe<br>in seconds.")
        prop.widget_add("c", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "previous")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of previous keyframe<br>in seconds.")
        prop.widget_add("p", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "next")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.tooltip_set("Time of next keyframe<br>in seconds.")
        prop.widget_add("n", wid)
        self["main"].property_add(prop)

        prop = Property(parent, "transition")
        wid = WidgetCombo(parent)
        for null, i in enumerate(self._transitions):
            wid.item_add(i)
        wid.tooltip_set("Transition effect to interpolation<br>"
                        "between the previous keyframe<br>and this.")
        prop.widget_add("type", wid)
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        wid.type_float()
        #wid.parser_in = lambda x: str(x)
        #wid.parser_out = lambda x: float(x)
        wid.tooltip_set("Transition time between the<br>"
                        "previous keyframe and this,<br>in seconds.")
        prop.widget_add("length", wid)
        self["main"].property_add(prop)

        self._parent.main_edje.signal_callback_add("timestop", "*",
                                                   self._timeline_cb)
        self._parent.main_edje.signal_callback_add("timeremove", "*",
                                                   self._timeremove_cb)
        self.e.callback_add("animation.removed", self._removed)
        self.e.animation.callback_add("animation.changed", self._update)
        self.e.animation.callback_add("animation.unselected", self._removed)
        self.e.animation.callback_add("state.added", self._timestop_add)
        self.e.animation.callback_add("frame.changed", self._update_states)
Exemplo n.º 20
0
class PartAnimStateDetails(PartStateDetails):
    def __init__(self,
                 parent,
                 operation_stack_cb,
                 img_new_img_cb=None,
                 img_list_get_cb=None,
                 img_id_get_cb=None,
                 fnt_new_fnt_cb=None,
                 fnt_list_get_cb=None,
                 workfile_name_get_cb=None,
                 part_object_get_cb=None,
                 group="editje/collapsable/part_properties"):
        PartStateDetails.__init__(self, parent, operation_stack_cb,
                                  img_new_img_cb, img_list_get_cb,
                                  img_id_get_cb, fnt_new_fnt_cb,
                                  fnt_list_get_cb, workfile_name_get_cb,
                                  part_object_get_cb, group)

    def _context_recall(self, **kargs):
        self.e.animation.name = kargs["animation"]
        self.e.animation.state = kargs["time"]
        self.e.part.name = kargs["part"]
        self.e.part.state.name = kargs["state"]

    def _header_init(self, parent):
        self.title = "part frame properties"

        self._header_table = PropertyTable(parent, "part name/type")
        self.content_set("part_state.swallow", self._header_table)

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        prop = Property(parent, "type")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        prop.widget_add("t", wid)
        self._header_table.property_add(prop)

        self._source_prop = Property(parent, "source widget")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        self._source_prop.widget_add("s", wid)
        self._header_table.property_add(self._source_prop)
        self._source_prop.hide()

        self._module_prop = Property(parent, "module")
        wid = WidgetEntry(self)
        wid.disabled_set(True)
        self._module_prop.widget_add("m", wid)
        self._header_table.property_add(self._module_prop)
        self._module_prop.hide()

        self.content_set("part_name.swallow", self._header_table)
        self.e.animation.callback_add("animation.changed", self._anim_selected)
        self.e.animation.callback_add("animation.unselected",
                                      self._anim_unselected)
        self.e.animation.callback_add("part.added", self._anim_parts_changed)
        self.e.animation.callback_add("part.removed", self._anim_parts_changed)

        self._state_copy_button = StateCopyButton(self.e)

        self.edje_get().signal_callback_add(
            "cl,option,clicked", "editje/collapsable",
            self._state_copy_button._floater_open)

    def _show(self):
        state = self.part_edje.state_selected_get()
        self._header_table["name"].value = self.part_edje.name
        self._header_table["name"].show_value()
        self._header_table["type"].value = \
            part_type_to_text(self.part_edje.type)
        self._header_table["type"].show_value()

        if self.e.part.type == edje.EDJE_PART_TYPE_EXTERNAL:
            source = self.e.part.source
            if source.startswith("elm/"):
                source = source[4:]
                module = "Elementary"
            else:
                module = "Emotion"

            self.edje_get().signal_emit("cl,extra,activate", "")
            if "source widget" not in self._header_table:
                self._header_table.property_add(self._source_prop)
            if "module" not in self._header_table:
                self._header_table.property_add(self._module_prop)

            self._header_table["source widget"].value = source
            self._header_table["source widget"].show_value()
            self._header_table["module"].value = module
            self._header_table["module"].show_value()
        else:
            self._header_extra_hide()

        self.edje_get().signal_emit("cl,option,enable", "editje")
        self.state = self.part_edje.state_get(*state)
        self._update()
        self.show()

    def _header_extra_hide(self):
        self.edje_get().signal_emit("cl,extra,deactivate", "")
        for p in ["source widget", "module"]:
            if p in self._header_table:
                self._header_table.property_del(p)

    def _hide(self):
        self._header_table["name"].value = None
        self._header_table["name"].hide_value()
        self._header_table["type"].value = None
        self._header_table["type"].hide_value()
        self._header_extra_hide()

        self.edje_get().signal_emit("cl,option,disable", "editje")
        self._hide_all()
        self.hide()

    def _check_and_show(self):
        anim = self.e.animation
        part = self.e.part
        ret = anim.name and anim.part_belongs(part.name)
        if ret:
            self._show()
        else:
            self._hide()
        return ret

    def _part_update(self, emissor, data):
        if self.part_evas:
            self.part_evas.on_resize_del(self._size_changed)
        self.part_edje = self.e.part._part
        self.part_evas = self._part_object_get_cb(self.part_edje.name)
        self.part_evas.on_resize_add(self._size_changed)
        self._size_changed(self.part_evas)

        self._check_and_show()

    def _part_unselected(self, emissor, data):
        if self.part_evas:
            self.part_evas.on_resize_del(self._size_changed)

        self.part_evas = None
        self.part_edje = None
        self._hide()

    def _anim_selected(self, emissor, data):
        self._check_and_show()

    def _anim_unselected(self, emissor, data):
        self._hide()

    def _anim_parts_changed(self, emissor, data):
        self._check_and_show()

    def _state_changed_cb(self, emissor, data):
        if not data:
            return
        self.part_edje.state_selected_set(*data)
        self.state = self.e.part.state._state
        if self._check_and_show():
            self._update()
Exemplo n.º 21
0
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(self,
                               parent,
                               operation_stack_cb,
                               group="editje/collapsable/part_state")

        self.title = "signal"

        self._parent = parent
        self._actions_added = 0

        self._header_table = PropertyTable(parent, "signal name",
                                           self._header_prop_value_changed)
        self.content_set("part_state.swallow", self._header_table)
        self.focus_custom_chain_set([self._header_table, self._box])

        prop = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Unique signal name.")
        prop.widget_add("n", wid)
        self._header_table.property_add(prop)

        popup_hide_cb_list = [(self.e.signal, "program.unselected"),
                              (self.e.signal, "program.changed")]

        prop = Property(parent, "signal")
        wid = WidgetSignal(self,
                           popup_hide_object_signal_list=popup_hide_cb_list)
        wid.tooltip_set(
            "Signal to be received.", "Click to select one common"
            "<br>signal to be received.")
        prop.widget_add("s", wid)
        self["main"].property_add(prop)

        def parts_get():
            return self.e.parts

        def animations_get():
            return self.e.animations

        self._prop_source_animations = Property(parent, "source")
        wid = WidgetSource(self, "Animation list", animations_get,
                           popup_hide_cb_list)
        wid.tooltip_set(
            "Accepted signal source.", "Click to select one "
            "existent<br>animation as source.")
        self._prop_source_animations.widget_add("s", wid)
        self["main"].property_add(self._prop_source_animations)
        self["main"].property_del("source")

        self._prop_source_parts = Property(parent, "source")
        wid = WidgetSource(self, "Parts list", parts_get, popup_hide_cb_list)
        wid.tooltip_set("Accepted signal source.", "Click to select one "
                        "existent<br>part as source.")
        self._prop_source_parts.widget_add("s", wid)
        self["main"].property_add(self._prop_source_parts)

        prop = Property(parent, "delay")
        wid = WidgetEntry(self)
        wid.parser_in = lambda x: str(x)
        wid.parser_out = lambda x: float(x)
        wid.tooltip_set(
            "Fixed delay to do the action in seconds. The<br>total "
            "delay is sum off fixed and variable delays.")
        prop.widget_add("delay", wid)
        wid = WidgetEntry(self)
        wid.parser_in = lambda x: str(x)
        wid.parser_out = lambda x: float(x)
        wid.tooltip_set(
            "Variable delay to do the action in seconds. Will<br>be"
            " selected one random value between 0 and this.")
        prop.widget_add("range", wid)
        self["main"].property_add(prop)

        self.group_add("api")
        prop = Property(parent, "export")
        wid = WidgetBoolean(self)
        wid.tooltip_set("Add this part to exported signals.")
        prop.widget_add("export", wid)
        self["api"].property_add(prop)
        self._prop_api_name = Property(parent, "name")
        wid = WidgetEntry(self)
        wid.tooltip_set("Export name of signal.")
        self._prop_api_name.widget_add("name", wid)
        self["api"].property_add(self._prop_api_name)
        self._prop_api_description = Property(parent, "description")
        wid = WidgetEntry(self)
        wid.tooltip_set("Description of exported signal.")
        self._prop_api_description.widget_add("description", wid)
        self["api"].property_add(self._prop_api_description)

        self.group_add("actions")

        self.group_add("out")

        prop = Property(parent, "signal")
        wid = WidgetSignal(self,
                           popup_hide_object_signal_list=popup_hide_cb_list)
        wid.tooltip_set("Signal to be emmited.", "Click to select one common "
                        "signal to be emmited.")
        prop.widget_add("s", wid)
        self["out"].property_add(prop)

        prop = Property(parent, "source")
        wid = WidgetSource(self, "Parts list", parts_get, popup_hide_cb_list)
        wid.tooltip_set("Name registered as signal source.", "Click to select "
                        "one existent<br>part as source.")
        prop.widget_add("s", wid)
        self["out"].property_add(prop)

        self.e.callback_add("signal.added", self._update)
        self.e.callback_add("signal.removed", self._removed)
        self.e.callback_add("group.changed", self._removed)
        self.e.signal.callback_add("program.changed", self._update)
        self.e.signal.callback_add("program.name.changed", self._update)
        self.e.signal.callback_add("program.unselected", self._removed)

        self.open = True
        self.open_disable = True
        self.show()
        self.__notification = None
Exemplo n.º 22
0
class EditjeDetails(elementary.Layout):
    def __init__(self,
                 parent,
                 operation_stack_cb,
                 group="editje/collapsable/default"):
        if not operation_stack_cb:
            raise TypeError("You must set a callback for operation stacking on"
                            " EditjeDetails objects.")

        elementary.Layout.__init__(self, parent)
        self.file_set(parent.themeext, group)
        self._edje = self.edje_get()

        self._parent = parent
        self._operation_stack_cb = operation_stack_cb

        self._proptable = PropertyTable(parent, "main",
                                        self.prop_value_changed)
        self._proptable.show()
        self.e = parent.e

        self._min_sizes_init(group)

        self._box = elementary.Box(parent)
        self._box.pack_end(self._proptable)
        self._box.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self._box.size_hint_align_set(evas.EVAS_HINT_FILL, 0.0)
        self._box.show()
        self.content_set("cl.content", self._box)
        self.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self.size_hint_align_set(evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL)
        self.size_hint_min_set(*self._min_size_collapsed)

        self._subgroups = dict()

        self._open_load()

    def _min_sizes_init(self, group):
        self._m_save = self._edje.size_min_calc()
        self._min_size_collapsed = self._m_save
        self._edje.signal_emit("cl,extra,activate", "")
        edje.message_signal_process()
        self._m_save_extra = self._edje.size_min_calc()
        self._edje.signal_emit("cl,extra,deactivate", "")
        self._min_size = self._min_size_collapsed

    def min_size_expanded_toggle(self, value):
        if value:
            self._min_size_collapsed = self._m_save_extra
        else:
            self._min_size_collapsed = self._m_save

    def _size_hint_changed_cb(self, obj):
        self._min_size = self._edje.size_min_calc()
        if self._open:
            self.size_hint_min_set(*self._min_size)

    def content_set(self, part, obj):
        obj.on_changed_size_hints_add(self._size_hint_changed_cb)
        elementary.Layout.content_set(self, part, obj)
        self._min_size = self._edje.size_min_calc()

    def group_add(self, name):
        if name in self._subgroups:
            raise KeyError(name)

        tbl = PropertyTable(self._parent, name, self.prop_value_changed)
        tbl.show()
        frm = elementary.Layout(self._parent)

        frm.file_set(self._parent.themeext, "subgroup")
        frm.edje_get().part_text_set("title.label", name)
        frm.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        frm.size_hint_align_set(evas.EVAS_HINT_FILL, 0.0)
        frm.content_set("content", tbl)
        frm.show()
        self._box.pack_end(frm)

        grp = dict()
        grp["table"] = tbl
        grp["frame"] = frm
        self._subgroups[name] = grp

    def group_title_set(self, name, title):
        if not name in self._subgroups:
            raise KeyError(name)

        self._subgroups[name]["frame"].edje_get().part_text_set(
            "title.label", title)

    def group_show(self, name):
        if not name in self._subgroups:
            raise KeyError(name)
        grp = self._subgroups[name]["frame"]
        self._box.pack_end(grp)
        grp.show()

    def group_hide(self, name):
        if not name in self._subgroups:
            raise KeyError(name)
        grp = self._subgroups[name]["frame"]
        self._box.unpack(grp)
        grp.hide()

    def main_hide(self):
        self._box.unpack(self._proptable)
        self._proptable.hide()

    def main_show(self):
        self._box.pack_end(self._proptable)
        self._proptable.show()

    def prop_value_changed(self, prop, value, group):
        pass

    def __getitem__(self, key):
        if key == "main":
            return self._proptable
        elif key in self._subgroups:
            return self._subgroups[key]["table"]
        raise KeyError(key)

    # Title
    def _title_set(self, value):
        self._edje.part_text_set("cl.header.title", value)

    def _title_get(self):
        return self.part_text_get("cl.header.title")

    title = property(_title_get, _title_set)

    #  Open / Close
    def _open_load(self):
        self._edje.signal_callback_add("cl,opened", "editje/collapsable",
                                       self._opened_cb)
        self._edje.signal_callback_add("cl,closed", "editje/collapsable",
                                       self._closed_cb)

        self._open = False
        self._open_disable = True
        self.open = False

    def _open_set(self, value):
        if self._open_disable:
            return
        self.open_set(value)

    def open_set(self, value):
        if value:
            self._edje.signal_emit("cl,open", "")
        else:
            self._edje.signal_emit("cl,close", "")

    def _opened_cb(self, obj, emission, source):
        self._open = True
        self.size_hint_weight_set(evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND)
        self.size_hint_min_set(*self._min_size)
        self._edje.calc_force()
        self._proptable.disabled_set(False)

    def _closed_cb(self, obj, emission, source):
        self._open = False
        self.size_hint_weight_set(evas.EVAS_HINT_EXPAND, 0.0)
        self.size_hint_min_set(*self._min_size_collapsed)
        self._edje.calc_force()
        self._proptable.disabled_set(True)

    def _open_get(self):
        return self._open

    open = property(_open_get, _open_set)

    def _open_disable_set(self, value):
        if value:
            self.edje_get().signal_emit("cl,disable", "")
        else:
            self.edje_get().signal_emit("cl,enable", "")
        self._open_disable = value

    def _open_disable_get(self, value):
        return self._open_disable

    open_disable = property(_open_disable_get, _open_disable_set)

    # most general form, specialise if needed
    def _context_recall(self, **kargs):
        self.e.part.name = kargs["part"]
        self.e.part.state.name = kargs["state"]

    # most general form, specialise if needed
    def _prop_old_values_get(self, prop_attrs, is_external):
        old_values = []
        obj = self._prop_object_get()

        for i, p in enumerate(prop_attrs):
            old_values.append(getattr(obj, p))

        return old_values

    def _prop_change_do(self, op_name, prop_groups, prop_names, prop_values,
                        prop_attrs, is_external, filters):
        def set_property(part_name,
                         state_name,
                         anim_name,
                         frame,
                         sig_name,
                         prop_attrs,
                         prop_names,
                         prop_values,
                         is_external,
                         filter_,
                         reverse=False):

            if reverse:
                efunc = lambda l: izip(xrange(len(l) - 1, -1, -1), reversed(l))
            else:
                efunc = enumerate

            self._context_recall(part=part_name,
                                 state=state_name,
                                 animation=anim_name,
                                 time=frame,
                                 signal=sig_name)

            for i, p in efunc(prop_attrs):
                if is_external[i]:
                    if not self.e.part.state.external_param_set(
                            prop_attrs[i], prop_values[i]):
                        return i
                else:
                    obj = self._prop_object_get()
                    setattr(obj, prop_attrs[i], prop_values[i])

                if filter_[i]:
                    label_value = filter_[i](prop_values[i])
                else:
                    label_value = prop_values[i]
                if self[prop_groups[i]][prop_names[i]].value != label_value:
                    self[prop_groups[i]][prop_names[i]].value = label_value
            return True

        if not self._prop_object_get:
            raise NotImplementedError(
                "One must implement self._prop_object_get for"
                " EditjeDetails children classes.")

        l = len(prop_groups)
        for arg in (prop_names, prop_values, prop_attrs, is_external, filters):
            if len(arg) != l:
                raise TypeError("Cardinality of property fields differ.")

        part_name = self.e.part.name
        state_name = self.e.part.state.name

        # animations' only
        anim_name = self.e.animation.name
        frame = self.e.animation.state

        # signals' only
        sig_name = self.e.signal.name

        old_values = []
        for i, p in enumerate(prop_attrs):
            if not p:
                prop_attrs[i] = prop_names[i]

        old_values = self._prop_old_values_get(prop_attrs, is_external)

        is_valid = set_property(part_name, state_name, anim_name, frame,
                                sig_name, prop_attrs, prop_names, prop_values,
                                is_external, filters)

        if is_valid is not True:
            self["external"][prop_attrs[is_valid]].value = old_values[is_valid]
            return

        op = Operation(op_name)
        op.redo_callback_add(set_property, part_name, state_name, anim_name,
                             frame, sig_name, prop_attrs, prop_names,
                             prop_values, is_external, filters)
        op.undo_callback_add(set_property, part_name, state_name, anim_name,
                             frame, sig_name, prop_attrs, prop_names,
                             old_values, is_external, filters, True)
        self._operation_stack_cb(op)

        return op