Example #1
0
    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()
Example #2
0
    def notify(self, message):
        if self.__notification:
            self.__notification.hide()
            self.__notification.delete()
            self.__notification = None
        self.__notification = Notify(self)
        self.__notification.timeout_set(2)
        self.__notification.orient_set(ELM_NOTIFY_ORIENT_TOP)

        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()
Example #3
0
class SignalDetails(EditjeDetails):
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(self,
                               parent,
                               operation_stack_cb,
                               group="editje/collapsable/part_state")

        self.title = "signal"

        self._parent = parent
        self._actions_added = 0

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

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

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

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

        def parts_get():
            return self.e.parts

        def animations_get():
            return self.e.animations

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

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

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

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

        self.group_add("actions")

        self.group_add("out")

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

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

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

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

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

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

        if prop_name != "name":
            return

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.open_set(False)

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

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

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

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

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

        action = self.e.signal.action

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

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

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

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

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

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

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

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

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

        self.open_set(True)
        self.show()

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

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

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

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

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

        self.__notification.show()

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

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

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

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

        elif group == "actions":

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

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

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

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

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

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

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

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

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

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

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

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

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

            elif prop == "source":

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

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

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

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

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

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

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

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

            if prop == "description":

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

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

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

            if prop == "export":

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

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

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

    def _update_api_props(self, export, api):
        self["api"]["export"].value = export
        if self["api"]["export"].value:
            if "name" not in self["api"]:
                self["api"].property_add(self._prop_api_name)
                self["api"].property_add(self._prop_api_description)
            self["api"]["name"].value = api[0]
            self["api"]["description"].value = api[1]
        elif "name" in self["api"]:
            self["api"].property_del("name")
            self["api"].property_del("description")
Example #4
0
class Wizard(InnerWindow):
    default_width = 500
    default_height = 500
    default_group = "editje/wizard"

    def __init__(self, parent, width=None, height=None, group=None):
        InnerWindow.__init__(self, parent)

        self._parent = parent
        #self.style_set("minimal")  # size fallbacks to __layout's min/max

        self.__layout = Layout(self)
        self.__edje = self.__layout.edje_get()
        self.__theme_file = sysconfig.theme_file_get("default")
        self.__width = width or self.default_width
        self.__height = height or self.default_height
        _group = group or self.default_group
        self.__layout.file_set(self.__theme_file, _group)
        self.__layout.size_hint_min_set(self.__width, self.__height)
        self.__layout.size_hint_max_set(self.__width, self.__height)

        self.on_key_down_add(self.__key_down_cb)

        InnerWindow.content_set(self, self.__layout)
        self.__layout.show()

        self.__pager = Naviframe(self)
        self.__pager.style_set("editje.rightwards")
        self.__pager.show()
        self.__layout.content_set("content", self.__pager)

        self.__pages = {}
        self.__current_page = None
        self.__notification = None

    def _subtitle_text_set(self, value):
        if not value:
            self.__edje.signal_emit("wizard,subtitle,hide", "")
            self.__edje.part_text_set("subtitle.text", "")
        else:
            self.__edje.signal_emit("wizard,subtitle,show", "")
            self.__edje.part_text_set("subtitle.text", value)

    subtitle_text = property(fset=_subtitle_text_set)

    def alternate_background_set(self, value):
        if value:
            self.__edje.signal_emit("wizard,bg,alternate", "")
        else:
            self.__edje.signal_emit("wizard,bg,default", "")

    def _title_text_set(self, value):
        if not value:
            self.__edje.part_text_set("title.text", "")
        else:
            self.__edje.part_text_set("title.text", value)

    title_text = property(fset=_title_text_set)

    def page_add(self, name, title="", subtitle="", separator=False):
        box = Box(self)
        box.size_hint_weight_set(evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND)
        box.show()

        content = Box(self)
        content.size_hint_weight_set(evas.EVAS_HINT_EXPAND,
                                     evas.EVAS_HINT_EXPAND)
        content.size_hint_align_set(evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL)
        box.pack_end(content)
        content.show()

        if separator:
            sp = Separator(self)
            sp.horizontal_set(True)
            box.pack_end(sp)
            sp.show()

        actions = Box(self)
        actions.horizontal_set(True)
        box.pack_end(actions)
        actions.show()

        self.__pages[name] = (title, subtitle, box, content, actions, {})
        self.title_text = title
        self.subtitle_text = subtitle
        self.__pager.item_simple_push(box)
        self.__current_page = name

    def content_add(self, pg_name, c):
        page = self.__pages.get(pg_name)
        if page:
            title, subtitle, box, content, actions, action_btns = page
            content.pack_end(c)

    # TODO: add support for equal-named actions on a page, if needed
    def action_add(self, pg_name, label, func_cb, data=None, icon=None,
                   key=None):
        page = self.__pages.get(pg_name)
        if page:
            title, subtitle, box, content, actions, action_btns = page

            btn = WizardAction(self._parent, label, func_cb, key, data)

            if icon:
                ico = Icon(self._parent)
                ico.file_set(self.__theme_file, "editje/icon/" + icon)
                btn.content_set(ico)
                ico.show()

            action_btns[label] = btn

            btn.show()
            actions.pack_end(btn)

    def action_disabled_set(self, pg_name, label, disabled):
        page = self.__pages.get(pg_name)
        if page:
            title, subtitle, box, content, actions, action_btns = page
            action_btns[label].disabled_set(disabled)

    def goto(self, page_name):
        page = self.__pages.get(page_name)
        if page:
            title, subtitle, box, content, actions, action_btns = page
            self.title_text = title
            self.subtitle_text = subtitle
            self.__pager.item_simple_promote(box)
            self.__current_page = page_name

    def notify(self, message):
        if self.__notification:
            self.__notification.hide()
            self.__notification.delete()
            self.__notification = None
        self.__notification = Notify(self)
        self.__notification.timeout_set(2)
        self.__notification.orient_set(ELM_NOTIFY_ORIENT_TOP)

        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 show(self):
        global _instance
        if _instance:
            _instance.hide()
        _instance = self

        # only Wizard InnerWindows are to be on top of the window blocker
        self._parent.block(True, self)
        InnerWindow.show(self)
        self.focus_set(True)

    def hide(self):
        global _instance
        if _instance == self:
            _instance = None
        InnerWindow.hide(self)
        self._parent.block(False)

    def open(self):
        self.show()

    def close(self):
        self._parent.focus_set(True)
        self.hide()
        self.delete()

    def __key_down_cb(self, obj, event):
        page = self.__pages.get(self.__current_page)
        if not page:
            return
        acts = page[-1]
        for a in acts.itervalues():
            if a.key == event.keyname:
                a()
                return
Example #5
0
class Wizard(InnerWindow):
    default_width = 500
    default_height = 500
    default_group = "editje/wizard"

    def __init__(self, parent, width=None, height=None, group=None):
        InnerWindow.__init__(self, parent)

        self._parent = parent
        #self.style_set("minimal")  # size fallbacks to __layout's min/max

        self.__layout = Layout(self)
        self.__edje = self.__layout.edje_get()
        self.__theme_file = sysconfig.theme_file_get("default")
        self.__width = width or self.default_width
        self.__height = height or self.default_height
        _group = group or self.default_group
        self.__layout.file_set(self.__theme_file, _group)
        self.__layout.size_hint_min_set(self.__width, self.__height)
        self.__layout.size_hint_max_set(self.__width, self.__height)

        self.on_key_down_add(self.__key_down_cb)

        InnerWindow.content_set(self, self.__layout)
        self.__layout.show()

        self.__pager = Naviframe(self)
        self.__pager.style_set("editje.rightwards")
        self.__pager.show()
        self.__layout.content_set("content", self.__pager)

        self.__pages = {}
        self.__current_page = None
        self.__notification = None

    def _subtitle_text_set(self, value):
        if not value:
            self.__edje.signal_emit("wizard,subtitle,hide", "")
            self.__edje.part_text_set("subtitle.text", "")
        else:
            self.__edje.signal_emit("wizard,subtitle,show", "")
            self.__edje.part_text_set("subtitle.text", value)

    subtitle_text = property(fset=_subtitle_text_set)

    def alternate_background_set(self, value):
        if value:
            self.__edje.signal_emit("wizard,bg,alternate", "")
        else:
            self.__edje.signal_emit("wizard,bg,default", "")

    def _title_text_set(self, value):
        if not value:
            self.__edje.part_text_set("title.text", "")
        else:
            self.__edje.part_text_set("title.text", value)

    title_text = property(fset=_title_text_set)

    def page_add(self, name, title="", subtitle="", separator=False):
        box = Box(self)
        box.size_hint_weight_set(evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND)
        box.show()

        content = Box(self)
        content.size_hint_weight_set(evas.EVAS_HINT_EXPAND,
                                     evas.EVAS_HINT_EXPAND)
        content.size_hint_align_set(evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL)
        box.pack_end(content)
        content.show()

        if separator:
            sp = Separator(self)
            sp.horizontal_set(True)
            box.pack_end(sp)
            sp.show()

        actions = Box(self)
        actions.horizontal_set(True)
        box.pack_end(actions)
        actions.show()

        self.__pages[name] = (title, subtitle, box, content, actions, {})
        self.title_text = title
        self.subtitle_text = subtitle
        self.__pager.item_simple_push(box)
        self.__current_page = name

    def content_add(self, pg_name, c):
        page = self.__pages.get(pg_name)
        if page:
            title, subtitle, box, content, actions, action_btns = page
            content.pack_end(c)

    # TODO: add support for equal-named actions on a page, if needed
    def action_add(self,
                   pg_name,
                   label,
                   func_cb,
                   data=None,
                   icon=None,
                   key=None):
        page = self.__pages.get(pg_name)
        if page:
            title, subtitle, box, content, actions, action_btns = page

            btn = WizardAction(self._parent, label, func_cb, key, data)

            if icon:
                ico = Icon(self._parent)
                ico.file_set(self.__theme_file, "editje/icon/" + icon)
                btn.content_set(ico)
                ico.show()

            action_btns[label] = btn

            btn.show()
            actions.pack_end(btn)

    def action_disabled_set(self, pg_name, label, disabled):
        page = self.__pages.get(pg_name)
        if page:
            title, subtitle, box, content, actions, action_btns = page
            action_btns[label].disabled_set(disabled)

    def goto(self, page_name):
        page = self.__pages.get(page_name)
        if page:
            title, subtitle, box, content, actions, action_btns = page
            self.title_text = title
            self.subtitle_text = subtitle
            self.__pager.item_simple_promote(box)
            self.__current_page = page_name

    def notify(self, message):
        if self.__notification:
            self.__notification.hide()
            self.__notification.delete()
            self.__notification = None
        self.__notification = Notify(self)
        self.__notification.timeout_set(2)
        self.__notification.orient_set(ELM_NOTIFY_ORIENT_TOP)

        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 show(self):
        global _instance
        if _instance:
            _instance.hide()
        _instance = self

        # only Wizard InnerWindows are to be on top of the window blocker
        self._parent.block(True, self)
        InnerWindow.show(self)
        self.focus_set(True)

    def hide(self):
        global _instance
        if _instance == self:
            _instance = None
        InnerWindow.hide(self)
        self._parent.block(False)

    def open(self):
        self.show()

    def close(self):
        self._parent.focus_set(True)
        self.hide()
        self.delete()

    def __key_down_cb(self, obj, event):
        page = self.__pages.get(self.__current_page)
        if not page:
            return
        acts = page[-1]
        for a in acts.itervalues():
            if a.key == event.keyname:
                a()
                return
Example #6
0
class SignalDetails(EditjeDetails):
    def __init__(self, parent, operation_stack_cb):
        EditjeDetails.__init__(self, parent, operation_stack_cb, group="editje/collapsable/part_state")

        self.title = "signal"

        self._parent = parent
        self._actions_added = 0

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

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

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

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

        def parts_get():
            return self.e.parts

        def animations_get():
            return self.e.animations

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

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

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

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

        self.group_add("actions")

        self.group_add("out")

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

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

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

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

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

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

        if prop_name != "name":
            return

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.open_set(False)

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

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

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

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

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

        action = self.e.signal.action

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

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

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

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

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

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

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

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

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

        self.open_set(True)
        self.show()

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

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

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

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

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

        self.__notification.show()

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

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

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

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

        elif group == "actions":

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

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

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

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

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

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

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

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

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

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

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

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

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

            elif prop == "source":

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

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

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

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

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

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

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

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

            if prop == "description":

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

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

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

            if prop == "export":

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

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

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

    def _update_api_props(self, export, api):
        self["api"]["export"].value = export
        if self["api"]["export"].value:
            if "name" not in self["api"]:
                self["api"].property_add(self._prop_api_name)
                self["api"].property_add(self._prop_api_description)
            self["api"]["name"].value = api[0]
            self["api"]["description"].value = api[1]
        elif "name" in self["api"]:
            self["api"].property_del("name")
            self["api"].property_del("description")