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 __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 _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 _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 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_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
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)
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
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)
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)
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)
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()
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")
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)
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
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")
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)
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()
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
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