Exemple #1
0
    def __init__(self, parent, base, units):
        self.base = base  # the divisor/multiplier for units
        self.units = units  # a list of strings with the base unit description at index 0

        super(UnitSpinner, self).__init__(parent)
        self.horizontal = True

        self.save_timer = None

        s = self.spinner = Spinner(parent)
        s.size_hint_weight = EXPAND_HORIZ
        s.size_hint_align = FILL_HORIZ
        s.min_max = 0, base
        s.show()
        self.pack_end(s)

        hs = self.hoversel = Hoversel(parent)
        for u in units:
            hs.item_add(u, None, 0, lambda x=hs, y=None, u=u: x.text_set(u))
        hs.show()
        self.pack_end(hs)
Exemple #2
0
    def __init__(self, parent, title, rfunc, wfunc):
        Frame.__init__(self, parent)
        self.size_hint_weight = EXPAND_HORIZ
        self.size_hint_align = FILL_HORIZ
        self.text = title

        t = Table(self, homogeneous=True, padding=(3, 3))
        t.size_hint_weight = EXPAND_HORIZ
        t.size_hint_align = FILL_HORIZ
        t.show()

        l = Label(self, text="Proxy type")
        l.size_hint_align = 0.0, 0.5
        l.show()
        ptype = Hoversel(parent)
        ptype.size_hint_align = -1.0, 0.5
        ptype.text = rfunc().type.name
        for n in self.proxy_types.iterkeys():
            ptype.item_add(n, callback=lambda x, y, z=n: ptype.text_set(z))
        ptype.show()
        t.pack(l, 0, 0, 1, 1)
        t.pack(ptype, 1, 0, 1, 1)

        l = Label(self, text="Hostname")
        l.size_hint_align = 0.0, 0.5
        l.show()
        phost = Entry(parent)
        phost.size_hint_weight = EXPAND_HORIZ
        phost.size_hint_align = FILL_HORIZ
        phost.single_line = True
        phost.scrollable = True
        phost.entry = rfunc().hostname
        phost.show()
        t.pack(l, 0, 1, 1, 1)
        t.pack(phost, 1, 1, 1, 1)

        l = Label(self, text="Port")
        l.size_hint_align = 0.0, 0.5
        l.show()
        pport = Spinner(parent)
        pport.size_hint_align = -1.0, 0.5
        pport.min_max = 0, 65535
        pport.value = rfunc().port
        pport.show()
        t.pack(l, 0, 2, 1, 1)
        t.pack(pport, 1, 2, 1, 1)

        l = Label(self, text="Username")
        l.size_hint_align = 0.0, 0.5
        l.show()
        puser = Entry(parent)
        puser.size_hint_weight = EXPAND_HORIZ
        puser.size_hint_align = FILL_HORIZ
        puser.single_line = True
        puser.scrollable = True
        puser.entry = rfunc().username
        puser.show()
        t.pack(l, 0, 3, 1, 1)
        t.pack(puser, 1, 3, 1, 1)

        l = Label(self, text="Password")
        l.size_hint_align = 0.0, 0.5
        l.show()
        ppass = Entry(parent)
        ppass.size_hint_weight = EXPAND_HORIZ
        ppass.size_hint_align = FILL_HORIZ
        ppass.single_line = True
        ppass.scrollable = True
        ppass.password = True
        ppass.entry = rfunc().password
        ppass.show()
        t.pack(l, 0, 4, 1, 1)
        t.pack(ppass, 1, 4, 1, 1)

        entries = [ptype, phost, pport, puser, ppass]

        save = Button(parent, text="Apply")
        save.callback_clicked_add(self.save_conf, wfunc, entries)
        save.show()
        t.pack(save, 0, 5, 2, 1)

        self.content = t
def fileselector_clicked(obj, item=None):
    win = StandardWindow("fileselector",
                         "File selector test",
                         autodel=True,
                         size=(500, 500))

    box1 = Box(win, horizontal=True, size_hint_weight=EXPAND_BOTH)
    win.resize_object_add(box1)
    box1.show()

    fs = Fileselector(win,
                      is_save=True,
                      expandable=False,
                      folder_only=False,
                      path=os.getenv("HOME"),
                      size_hint_weight=EXPAND_BOTH,
                      size_hint_align=FILL_BOTH)
    fs.callback_done_add(fs_cb_done, win)
    fs.callback_selected_add(fs_cb_selected, win)
    fs.callback_directory_open_add(fs_cb_directory_open, win)
    box1.pack_end(fs)
    fs.show()

    fs.custom_filter_append(custom_filter_all, filter_name="All Files")
    fs.custom_filter_append(custom_filter_edje, filter_name="Edje Files")
    fs.mime_types_filter_append(["text/*"], "Text Files")
    fs.mime_types_filter_append(["image/*"], "Image Files")

    sep = Separator(win)
    box1.pack_end(sep)
    sep.show()

    vbox = Box(win)
    box1.pack_end(vbox)
    vbox.show()

    # Options frame
    fr = Frame(win, text="Options")
    vbox.pack_end(fr)
    fr.show()

    fbox1 = Box(win)
    fr.content = fbox1
    fbox1.show()

    fbox2 = Box(win, horizontal=True)
    fbox1.pack_end(fbox2)
    fbox2.show()

    ck = Check(win, text="is_save", state=fs.is_save)
    ck.callback_changed_add(ck_cb_is_save, fs)
    fbox2.pack_end(ck)
    ck.show()

    ck = Check(win, text="folder_only", state=fs.folder_only)
    ck.callback_changed_add(ck_cb_folder_only, fs)
    fbox2.pack_end(ck)
    ck.show()

    ck = Check(win, text="expandable", state=fs.expandable)
    ck.callback_changed_add(ck_cb_expandable, fs)
    fbox2.pack_end(ck)
    ck.show()

    fbox2 = Box(win, horizontal=True)
    fbox1.pack_end(fbox2)
    fbox2.show()

    ck = Check(win, text="multiple selection", state=fs.multi_select)
    ck.callback_changed_add(ck_cb_multi_select, fs)
    fbox2.pack_end(ck)
    ck.show()

    ck = Check(win, text="buttons", state=fs.buttons_ok_cancel)
    ck.callback_changed_add(ck_cb_buttons, fs)
    fbox2.pack_end(ck)
    ck.show()

    ck = Check(win, text="hidden", state=fs.hidden_visible)
    ck.callback_changed_add(ck_cb_hidden, fs)
    fbox2.pack_end(ck)
    ck.show()

    # Getters frame
    fr = Frame(win, text="Getters", size_hint_align=FILL_BOTH)
    vbox.pack_end(fr)
    fr.show()

    fbox = Box(win, horizontal=True)
    fr.content = fbox
    fbox.show()

    bt = Button(win, text="selected_get")
    bt.callback_clicked_add(bt_cb_sel_get, fs)
    fbox.pack_end(bt)
    bt.show()

    bt = Button(win, text="path_get")
    bt.callback_clicked_add(bt_cb_path_get, fs)
    fbox.pack_end(bt)
    bt.show()

    bt = Button(win, text="selected_paths")
    bt.callback_clicked_add(bt_cb_paths_get, fs)
    fbox.pack_end(bt)
    bt.show()

    # Mode frame
    fr = Frame(win, text="Mode", size_hint_align=FILL_BOTH)
    vbox.pack_end(fr)
    fr.show()

    fbox = Box(win, horizontal=True)
    fr.content = fbox
    fbox.show()

    rdg = rd = Radio(win, text="List", state_value=ELM_FILESELECTOR_LIST)
    rd.callback_changed_add(rd_cb_mode, fs)
    fbox.pack_end(rd)
    rd.show()

    rd = Radio(win, text="Grid", state_value=ELM_FILESELECTOR_GRID)
    rd.callback_changed_add(rd_cb_mode, fs)
    rd.group_add(rdg)
    fbox.pack_end(rd)
    rd.show()

    # Thumbsize frame
    fr = Frame(win, text="Thumbnail size", size_hint_align=FILL_BOTH)
    vbox.pack_end(fr)
    fr.show()

    sl = Slider(win,
                min_max=(4, 130),
                unit_format="%.0f px",
                value=fs.thumbnail_size[0])
    sl.callback_delay_changed_add(sl_cb_thumb_size, fs)
    fr.content = sl
    sl.show()

    # Sort method frame
    fr = Frame(win, text="Sort method", size_hint_align=FILL_BOTH)
    vbox.pack_end(fr)
    fr.show()

    hs = Hoversel(win, text="File name (asc)")
    sorts = (
        ("File name (asc)", ELM_FILESELECTOR_SORT_BY_FILENAME_ASC),
        ("File name (desc)", ELM_FILESELECTOR_SORT_BY_FILENAME_DESC),
        ("Type (asc)", ELM_FILESELECTOR_SORT_BY_TYPE_ASC),
        ("Type (desc)", ELM_FILESELECTOR_SORT_BY_TYPE_DESC),
        ("Size (asc)", ELM_FILESELECTOR_SORT_BY_SIZE_ASC),
        ("Size (desc)", ELM_FILESELECTOR_SORT_BY_SIZE_DESC),
        ("Modified time (asc)", ELM_FILESELECTOR_SORT_BY_MODIFIED_ASC),
        ("Modified time (desc)", ELM_FILESELECTOR_SORT_BY_MODIFIED_DESC),
    )
    for sort in sorts:
        hs.item_add(label=sort[0],
                    callback=hs_cb_sort_method,
                    fs=fs,
                    method=sort[1])
    fr.content = hs
    hs.show()

    win.show()
    def __init__(self, parent, title, rfunc, wfunc):
        Frame.__init__(self, parent)
        self.size_hint_weight = EXPAND_HORIZ
        self.size_hint_align = FILL_HORIZ
        self.text = title

        t = Table(self, homogeneous=True, padding=(3,3))
        t.size_hint_weight = EXPAND_HORIZ
        t.size_hint_align = FILL_HORIZ
        t.show()

        l = Label(self, text="Proxy type")
        l.size_hint_align = 0.0, 0.5
        l.show()
        ptype = Hoversel(parent)
        ptype.size_hint_align = -1.0, 0.5
        ptype.text = rfunc().type.name
        for n in self.proxy_types.iterkeys():
            ptype.item_add(n, callback=lambda x, y, z=n: ptype.text_set(z))
        ptype.show()
        t.pack(l, 0, 0, 1, 1)
        t.pack(ptype, 1, 0, 1, 1)

        l = Label(self, text="Hostname")
        l.size_hint_align = 0.0, 0.5
        l.show()
        phost = Entry(parent)
        phost.size_hint_weight = EXPAND_HORIZ
        phost.size_hint_align = FILL_HORIZ
        phost.single_line = True
        phost.scrollable = True
        phost.entry = rfunc().hostname
        phost.show()
        t.pack(l, 0, 1, 1, 1)
        t.pack(phost, 1, 1, 1, 1)

        l = Label(self, text="Port")
        l.size_hint_align = 0.0, 0.5
        l.show()
        pport = Spinner(parent)
        pport.size_hint_align = -1.0, 0.5
        pport.min_max = 0, 65535
        pport.value = rfunc().port
        pport.show()
        t.pack(l, 0, 2, 1, 1)
        t.pack(pport, 1, 2, 1, 1)

        l = Label(self, text="Username")
        l.size_hint_align = 0.0, 0.5
        l.show()
        puser = Entry(parent)
        puser.size_hint_weight = EXPAND_HORIZ
        puser.size_hint_align = FILL_HORIZ
        puser.single_line = True
        puser.scrollable = True
        puser.entry = rfunc().username
        puser.show()
        t.pack(l, 0, 3, 1, 1)
        t.pack(puser, 1, 3, 1, 1)

        l = Label(self, text="Password")
        l.size_hint_align = 0.0, 0.5
        l.show()
        ppass = Entry(parent)
        ppass.size_hint_weight = EXPAND_HORIZ
        ppass.size_hint_align = FILL_HORIZ
        ppass.single_line = True
        ppass.scrollable = True
        ppass.password = True
        ppass.entry = rfunc().password
        ppass.show()
        t.pack(l, 0, 4, 1, 1)
        t.pack(ppass, 1, 4, 1, 1)

        entries = [ptype, phost, pport, puser, ppass]

        save = Button(parent, text="Apply")
        save.callback_clicked_add(self.save_conf, wfunc, entries)
        save.show()
        t.pack(save, 0, 5, 2, 1)

        self.content = t
Exemple #5
0
def slideshow_clicked(obj):
    win = StandardWindow("slideshow",
                         "Slideshow",
                         autodel=True,
                         size=(500, 400))

    ss = Slideshow(win, loop=True, size_hint_weight=EXPAND_BOTH)
    win.resize_object_add(ss)
    ss.show()

    ssc = ssClass()
    ss.item_add(ssc, os.path.join(img_path, images[0]))
    ss.item_add(ssc, os.path.join(img_path, images[1]))
    ss.item_add(ssc, os.path.join(img_path, images[2]))
    ss.item_add(ssc, os.path.join(img_path, images[3]))
    ss.item_add(ssc, os.path.join(img_path, images[8]))
    ss.item_add(ssc, os.path.join(img_path, images[4]))
    ss.item_add(ssc, os.path.join(img_path, images[5]))
    ss.item_add(ssc, os.path.join(img_path, images[6]))
    slide_last_it = ss.item_add(ssc, os.path.join(img_path, images[7]))
    ss.callback_transition_end_add(slide_transition, slide_last_it)

    bx = Box(win, horizontal=True)
    bx.show()

    no = Notify(win,
                align=(0.5, 1.0),
                size_hint_weight=EXPAND_BOTH,
                timeout=3.0,
                content=bx)
    win.resize_object_add(no)

    bx.event_callback_add(EVAS_CALLBACK_MOUSE_IN, mouse_in, no)
    bx.event_callback_add(EVAS_CALLBACK_MOUSE_OUT, mouse_out, no)

    bt = Button(win, text="Previous")
    bt.callback_clicked_add(previous, ss)
    bx.pack_end(bt)
    bt.show()

    bt = Button(win, text="Next")
    bt.callback_clicked_add(next, ss)
    bx.pack_end(bt)
    bt.show()

    hv = Hoversel(win, hover_parent=win, text=ss.transitions[0])
    bx.pack_end(hv)
    for transition in ss.transitions:
        hv.item_add(transition, None, 0, hv_select, ss, transition)
    hv.item_add("None", None, 0, hv_select, ss, None)
    hv.show()

    hv = Hoversel(win, hover_parent=win, text=ss.layout)
    bx.pack_end(hv)
    for layout in ss.layouts:
        hv.item_add(layout, None, 0, layout_select, ss, layout)
    hv.show()

    sp = Spinner(win,
                 label_format="%2.0f secs.",
                 step=1,
                 min_max=(1, 30),
                 value=3)
    sp.callback_changed_add(spin, ss)
    bx.pack_end(sp)
    sp.show()

    bt_start = Button(win, text="Start")
    bt_stop = Button(win, text="Stop", disabled=True)

    bt_start.callback_clicked_add(start, ss, sp, bt_start, bt_stop)
    bx.pack_end(bt_start)
    bt_start.show()

    bt_stop.callback_clicked_add(stop, ss, sp, bt_start, bt_stop)
    bx.pack_end(bt_stop)
    bt_stop.show()

    ss.event_callback_add(EVAS_CALLBACK_MOUSE_UP, notify_show, no)
    ss.event_callback_add(EVAS_CALLBACK_MOUSE_MOVE, notify_show, no)

    win.show()
def fileselector_clicked(obj, item=None):
    win = StandardWindow("fileselector", "File selector test",
                         autodel=True, size=(500,500))

    box1 = Box(win, horizontal=True, size_hint_weight=EXPAND_BOTH)
    win.resize_object_add(box1)
    box1.show()

    fs = Fileselector(win, is_save=True, expandable=False, folder_only=False,
                      path=os.getenv("HOME"), size_hint_weight=EXPAND_BOTH,
                      size_hint_align=FILL_BOTH)
    fs.callback_done_add(fs_cb_done, win)
    fs.callback_selected_add(fs_cb_selected, win)
    fs.callback_directory_open_add(fs_cb_directory_open, win)
    box1.pack_end(fs)
    fs.show()

    fs.custom_filter_append(custom_filter_all, filter_name="All Files")
    fs.custom_filter_append(custom_filter_edje, filter_name="Edje Files")
    fs.mime_types_filter_append(["text/*"], "Text Files")
    fs.mime_types_filter_append(["image/*"], "Image Files")


    sep = Separator(win)
    box1.pack_end(sep)
    sep.show()

    vbox = Box(win)
    box1.pack_end(vbox)
    vbox.show()

    # Options frame
    fr = Frame(win, text="Options")
    vbox.pack_end(fr)
    fr.show()

    fbox1 = Box(win)
    fr.content = fbox1
    fbox1.show()

    fbox2 = Box(win, horizontal=True)
    fbox1.pack_end(fbox2)
    fbox2.show()

    ck = Check(win, text="is_save", state=fs.is_save)
    ck.callback_changed_add(ck_cb_is_save, fs)
    fbox2.pack_end(ck)
    ck.show()

    ck = Check(win, text="folder_only", state=fs.folder_only)
    ck.callback_changed_add(ck_cb_folder_only, fs)
    fbox2.pack_end(ck)
    ck.show()

    ck = Check(win, text="expandable", state=fs.expandable)
    ck.callback_changed_add(ck_cb_expandable, fs)
    fbox2.pack_end(ck)
    ck.show()

    fbox2 = Box(win, horizontal=True)
    fbox1.pack_end(fbox2)
    fbox2.show()

    ck = Check(win, text="multiple selection", state=fs. multi_select)
    ck.callback_changed_add(ck_cb_multi_select, fs)
    fbox2.pack_end(ck)
    ck.show()

    ck = Check(win, text="buttons", state=fs.buttons_ok_cancel)
    ck.callback_changed_add(ck_cb_buttons, fs)
    fbox2.pack_end(ck)
    ck.show()

    ck = Check(win, text="hidden", state=fs.hidden_visible)
    ck.callback_changed_add(ck_cb_hidden, fs)
    fbox2.pack_end(ck)
    ck.show()

    # Getters frame
    fr = Frame(win, text="Getters", size_hint_align=FILL_BOTH)
    vbox.pack_end(fr)
    fr.show()

    fbox = Box(win, horizontal=True)
    fr.content = fbox
    fbox.show()

    bt = Button(win, text="selected_get")
    bt.callback_clicked_add(bt_cb_sel_get, fs)
    fbox.pack_end(bt)
    bt.show()

    bt = Button(win, text="path_get")
    bt.callback_clicked_add(bt_cb_path_get, fs)
    fbox.pack_end(bt)
    bt.show()

    bt = Button(win, text="selected_paths")
    bt.callback_clicked_add(bt_cb_paths_get, fs)
    fbox.pack_end(bt)
    bt.show()

    # Mode frame
    fr = Frame(win, text="Mode", size_hint_align=FILL_BOTH)
    vbox.pack_end(fr)
    fr.show()

    fbox = Box(win, horizontal=True)
    fr.content = fbox
    fbox.show()

    rdg = rd = Radio(win, text="List", state_value=ELM_FILESELECTOR_LIST)
    rd.callback_changed_add(rd_cb_mode, fs)
    fbox.pack_end(rd)
    rd.show()

    rd = Radio(win, text="Grid", state_value=ELM_FILESELECTOR_GRID)
    rd.callback_changed_add(rd_cb_mode, fs)
    rd.group_add(rdg)
    fbox.pack_end(rd)
    rd.show()

    # Thumbsize frame
    fr = Frame(win, text="Thumbnail size", size_hint_align=FILL_BOTH)
    vbox.pack_end(fr)
    fr.show()

    sl = Slider(win, min_max=(4, 130), unit_format="%.0f px",
                value=fs.thumbnail_size[0])
    sl.callback_delay_changed_add(sl_cb_thumb_size, fs)
    fr.content = sl
    sl.show()

    # Sort method frame
    fr = Frame(win, text="Sort method", size_hint_align=FILL_BOTH)
    vbox.pack_end(fr)
    fr.show()

    hs = Hoversel(win, text="File name (asc)")
    sorts = (
        ("File name (asc)", ELM_FILESELECTOR_SORT_BY_FILENAME_ASC),
        ("File name (desc)", ELM_FILESELECTOR_SORT_BY_FILENAME_DESC),
        ("Type (asc)", ELM_FILESELECTOR_SORT_BY_TYPE_ASC),
        ("Type (desc)", ELM_FILESELECTOR_SORT_BY_TYPE_DESC),
        ("Size (asc)", ELM_FILESELECTOR_SORT_BY_SIZE_ASC),
        ("Size (desc)", ELM_FILESELECTOR_SORT_BY_SIZE_DESC),
        ("Modified time (asc)", ELM_FILESELECTOR_SORT_BY_MODIFIED_ASC),
        ("Modified time (desc)", ELM_FILESELECTOR_SORT_BY_MODIFIED_DESC),
    )
    for sort in sorts:
        hs.item_add(label=sort[0], callback=hs_cb_sort_method, fs=fs, method=sort[1])
    fr.content = hs
    hs.show()

    win.show()
    def __init__(self,
                 parent_widget,
                 *args,
                 default_path='',
                 default_populate=True,
                 **kwargs):
        Box.__init__(self, parent_widget, *args, **kwargs)

        self.cancel_cb = None
        self.action_cb = None
        self.cb_dir_change = None

        self.threaded_fn = ThreadedFunction()
        # pylint: disable=c-extension-no-member
        self._timer = ecore.Timer(0.02, self.populate_file)

        # Watch key presses for ctrl+l to select entry
        parent_widget.elm_event_callback_add(self.cb_events)

        self.selected_dir = None
        self.show_hidden = False
        self.cur_dir = None
        self.focused_entry = None
        self.dir_only = False
        self.sort_reverse = False
        self.adding_hidden = False
        self.pending_files = deque()
        self.cur_subdirs = []
        self.cur_files = []

        # Mode should be 'save' or 'load'
        self.mode = 'save'

        self.home = os.path.expanduser('~')

        desktop = os.environ.get('XDG_DESKTOP_DIR')
        if desktop:
            self.desktop = desktop
        else:
            self.desktop = self.home + '/Desktop'

        self.root = '/'

        # Label+Entry for File Name
        self.filename_bx = Box(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.filename_bx.horizontal = True
        self.filename_bx.show()

        file_label = Label(self,
                           size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                           size_hint_align=FILL_HORIZ)
        file_label.text = 'Filename:'
        file_label.show()

        self.file_entry = Entry(self,
                                size_hint_weight=EXPAND_BOTH,
                                size_hint_align=FILL_HORIZ)
        self.file_entry.single_line_set(True)
        self.file_entry.scrollable_set(True)
        self.file_entry.callback_changed_user_add(self.cb_file_entry)
        self.file_entry.show()

        self.filename_bx.pack_end(file_label)
        self.filename_bx.pack_end(self.file_entry)

        sep = Separator(self,
                        size_hint_weight=EXPAND_HORIZ,
                        size_hint_align=FILL_HORIZ)
        sep.horizontal_set(True)
        sep.show()

        # Label+Entry for File Path
        self.filepath_bx = Box(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.filepath_bx.horizontal = True
        self.filepath_bx.show()

        file_label = Label(self,
                           size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                           size_hint_align=FILL_HORIZ)
        file_label.text = 'Current Folder:'
        file_label.show()

        self.filepath_en = Entry(self,
                                 size_hint_weight=EXPAND_BOTH,
                                 size_hint_align=FILL_HORIZ)
        self.filepath_en.single_line_set(True)
        self.filepath_en.scrollable_set(True)
        self.filepath_en.callback_changed_user_add(self.cb_file_entry)
        self.filepath_en.callback_unfocused_add(self.cb_filepath_en)
        self.filepath_en.callback_activated_add(self.cb_filepath_en)
        # Wish this worked. Doesn't seem to do anything
        # Working now EFL 1.22 ?
        self.filepath_en.input_hint_set(ELM_INPUT_HINT_AUTO_COMPLETE)

        if default_path and os.path.isdir(default_path):
            start = default_path
        else:
            start = self.home
        self.filepath_en.show()

        self.filepath_bx.pack_end(file_label)
        self.filepath_bx.pack_end(self.filepath_en)

        self.autocomplete_hover = Hoversel(self, hover_parent=self)
        self.autocomplete_hover.callback_selected_add(self.cb_hover)
        self.autocomplete_hover.show()

        self.file_selector_bx = Panes(self,
                                      content_left_size=0.3,
                                      size_hint_weight=EXPAND_BOTH,
                                      size_hint_align=FILL_BOTH)
        self.file_selector_bx.show()
        # Bookmarks Box contains:
        #
        # - Button - Up Arrow
        # - List - Home/Desktop/Root/GTK bookmarks
        # - Box
        # -- Button - Add Bookmark
        # -- Button - Remove Bookmark
        self.bookmark_bx = Box(self,
                               size_hint_weight=(0.3, EVAS_HINT_EXPAND),
                               size_hint_align=FILL_BOTH)
        self.bookmark_bx.show()

        up_ic = Icon(self,
                     size_hint_weight=EXPAND_BOTH,
                     size_hint_align=FILL_BOTH,
                     order_lookup=ELM_ICON_LOOKUP_THEME)
        up_ic.standard_set('arrow-up')
        up_ic.show()

        self.up_btn = Button(self,
                             size_hint_weight=EXPAND_HORIZ,
                             size_hint_align=FILL_HORIZ,
                             content=up_ic)
        self.up_btn.text = 'Up'
        self.up_btn.callback_pressed_add(self.cb_up_btn)
        self.up_btn.show()

        self.bookmarks_lst = List(self,
                                  size_hint_weight=EXPAND_BOTH,
                                  size_hint_align=FILL_BOTH)
        self.bookmarks_lst.callback_activated_add(self.cb_bookmarks_lst)
        self.bookmarks_lst.show()

        self.bookmark_modbox = Box(self,
                                   size_hint_weight=EXPAND_HORIZ,
                                   size_hint_align=FILL_HORIZ)
        self.bookmark_modbox.horizontal = True
        self.bookmark_modbox.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('list-add')
        con.show()

        self.add_btn = Button(self,
                              size_hint_weight=EXPAND_HORIZ,
                              size_hint_align=FILL_HORIZ,
                              content=con)
        self.add_btn.callback_pressed_add(self.cb_add_btn)
        self.add_btn.disabled = True
        self.add_btn.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('list-remove')
        con.show()

        self.rm_btn = Button(self,
                             size_hint_weight=EXPAND_HORIZ,
                             size_hint_align=FILL_HORIZ,
                             content=con)
        self.rm_btn.callback_pressed_add(self.cb_remove)
        self.rm_btn.disabled = True
        self.rm_btn.show()

        self.bookmark_modbox.pack_end(self.add_btn)
        self.bookmark_modbox.pack_end(self.rm_btn)

        self.bookmark_bx.pack_end(self.up_btn)
        self.bookmark_bx.pack_end(self.bookmarks_lst)
        self.bookmark_bx.pack_end(self.bookmark_modbox)

        # Directory List
        self.file_list_bx = Box(self,
                                size_hint_weight=EXPAND_BOTH,
                                size_hint_align=FILL_BOTH)
        self.file_list_bx.show()

        self.file_sort_btn = Button(self,
                                    size_hint_weight=EXPAND_HORIZ,
                                    size_hint_align=FILL_HORIZ)
        self.file_sort_btn.text = u'⬆ Name'
        self.file_sort_btn.callback_pressed_add(self.cb_sort)
        self.file_sort_btn.show()

        self.file_lst = Genlist(self,
                                size_hint_weight=EXPAND_BOTH,
                                size_hint_align=FILL_BOTH,
                                homogeneous=True,
                                mode=ELM_LIST_COMPRESS)
        self.file_lst.callback_activated_add(self.cb_file_lst)
        self.file_lst.show()

        self.preview = preview = Image(self)
        preview.size_hint_align = FILL_BOTH
        preview.show()

        self.file_list_bx.pack_end(self.file_sort_btn)
        self.file_list_bx.pack_end(self.file_lst)
        self.file_list_bx.pack_end(self.preview)

        self.file_selector_bx.part_content_set('left', self.bookmark_bx)
        self.file_selector_bx.part_content_set('right', self.file_list_bx)

        # Cancel and Save/Open button
        self.button_bx = Box(self,
                             size_hint_weight=EXPAND_HORIZ,
                             size_hint_align=(1.0, 0.5))
        self.button_bx.horizontal = True
        self.button_bx.show()

        self.action_ic = Icon(self,
                              size_hint_weight=EXPAND_BOTH,
                              size_hint_align=FILL_BOTH)
        self.action_ic.standard_set('document-save')
        self.action_ic.show()

        self.action_btn = Button(self,
                                 size_hint_weight=(0.0, 0.0),
                                 size_hint_align=(1.0, 0.5),
                                 content=self.action_ic)
        self.action_btn.text = 'Save  '
        self.action_btn.callback_pressed_add(self.cb_action_btn)
        self.action_btn.show()

        cancel_ic = Icon(self,
                         size_hint_weight=EXPAND_BOTH,
                         size_hint_align=FILL_BOTH)
        cancel_ic.standard_set('application-exit')
        cancel_ic.show()

        self.cancel_btn = Button(self,
                                 size_hint_weight=(0.0, 0.0),
                                 size_hint_align=(1.0, 0.5),
                                 content=cancel_ic)
        self.cancel_btn.text = 'Cancel  '
        self.cancel_btn.callback_pressed_add(self.cb_cancel_btn)
        self.cancel_btn.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('edit-find')
        con.show()

        self.hidden_btn = Button(self,
                                 size_hint_weight=(0.0, 0.0),
                                 size_hint_align=(1.0, 0.5),
                                 content=con)
        self.hidden_btn.text = 'Toggle Hidden  '
        self.hidden_btn.callback_pressed_add(self.cb_toggle_hidden)
        self.hidden_btn.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('folder-new')
        con.show()

        self.create_dir_btn = Button(self,
                                     size_hint_weight=(0.0, 0.0),
                                     size_hint_align=(1.0, 0.5),
                                     content=con)
        self.create_dir_btn.text = 'Create Folder  '
        self.create_dir_btn.callback_pressed_add(self.cb_create_dir)
        self.create_dir_btn.show()

        self.button_bx.pack_end(self.create_dir_btn)
        self.button_bx.pack_end(self.hidden_btn)
        self.button_bx.pack_end(self.cancel_btn)
        self.button_bx.pack_end(self.action_btn)

        self.pack_end(self.filename_bx)
        self.pack_end(sep)
        self.pack_end(self.filepath_bx)
        self.pack_end(self.autocomplete_hover)
        self.pack_end(self.file_selector_bx)
        self.pack_end(self.button_bx)

        self.populate_bookmarks()

        self.create_popup = Popup(self)
        self.create_popup.part_text_set('title,text', 'Create Folder:')

        self.create_en = Entry(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.create_en.single_line_set(True)
        self.create_en.scrollable_set(True)
        self.create_en.show()

        self.create_popup.content = self.create_en

        bt0 = Button(self, text='Create')
        bt0.callback_clicked_add(self.cb_create_folder)
        self.create_popup.part_content_set('button1', bt0)
        bt1 = Button(self, text='Cancel')
        bt1.callback_clicked_add(self.cb_close_popup)
        self.create_popup.part_content_set('button2', bt1)

        self.recent = None  # keeps pylint happy:
        if default_populate:
            self.populate_files(start)
Exemple #8
0
    def populate(self):
        # main vertical box
        box = Box(self, size_hint_weight = EXPAND_BOTH)
        self.resize_object_add(box)
        box.show()

        ### header
        fr = Frame(self, style='outdent_bottom', size_hint_weight=EXPAND_HORIZ,
                   size_hint_align=FILL_BOTH)
        box.pack_end(fr)
        fr.show()

        tb = Table(self, padding=(3,3),
                   size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH)
        fr.content = tb
        tb.show()

        # main menu button
        bt = MainMenuButton(self.app)
        tb.pack(bt, 0, 0, 1, 1)
        bt.show()

        # editable description entry
        self.caption_label = EditableDescription(self.app)
        tb.pack(self.caption_label, 1, 0, 1, 1)
        self.caption_label.show()

        # status label + button
        lb = Entry(self, editable=False, line_wrap=ELM_WRAP_NONE)
        lb.text_style_user_push("DEFAULT='align=center'")
        tb.pack(lb, 2, 0, 1, 1)
        lb.show()
        self.status_label = lb

        # branch selector
        self.branch_selector = Hoversel(self, text='HEAD', disabled=True,
                                        content=SafeIcon(self, 'git-branch'))
        self.branch_selector.callback_selected_add(self.branch_selected_cb)
        tb.pack(self.branch_selector, 3, 0, 1, 1)
        self.branch_selector.show()

        # pull button
        bt = Button(self, text='Pull', disabled=True,
                    content=SafeIcon(self, 'git-pull'))
        bt.callback_clicked_add(self.app.action_pull)
        tb.pack(bt, 4, 0, 1, 1)
        bt.show()
        self.pull_btn = bt

        # push button
        bt = Button(self, text='Push', disabled=True,
                    content=SafeIcon(self, 'git-push'))
        bt.callback_clicked_add(self.app.action_push)
        tb.pack(bt, 5, 0, 1, 1)
        bt.show()
        self.push_btn = bt

        ### Tree panes
        panes1 = Panes(self, content_left_min_size=200, content_left_size=0.0,
                      size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        box.pack_end(panes1)
        panes1.show()

        # the sidebar on the left
        self.sidebar = Sidebar(self, self.app)
        panes1.part_content_set('left', self.sidebar)

        ### Main content (left + right panes)
        panes2 = Panes(self, content_left_size=0.5,
                       size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        panes1.part_content_set('right', panes2)
        panes2.show()

        # the dag graph in the center
        self.graph = DagGraph(self, self.app)
        panes2.part_content_set('left', self.graph)

        # the diff viewer on the right
        self.diff_view = DiffViewer(self, self.app)
        self.diff_view.size_hint_weight = EXPAND_BOTH
        self.diff_view.size_hint_align = 0.0, 0.0
        panes2.part_content_set('right', self.diff_view)

        #
        self.show()
    def __init__(self, parent_widget, defaultPath="", defaultPopulate=True, *args, **kwargs):
        Box.__init__(self, parent_widget, *args, **kwargs)

        self.cancelCallback = None
        self.actionCallback = None
        self.directoryChangeCallback = None
        
        self.threadedFunction = ThreadedFunction()
        self._timer = ecore.Timer(0.02, self.populateFile)

        #Watch key presses for ctrl+l to select entry
        parent_widget.elm_event_callback_add(self.eventsCb)

        self.selectedFolder = None
        self.showHidden = False
        self.currentDirectory = None
        self.focusedEntry = None
        self.folderOnly = False
        self.sortReverse = False
        self.addingHidden = False
        self.pendingFiles = deque()
        self.currentSubFolders = []
        self.currentFiles = []

        #Mode should be "save" or "load"
        self.mode = "save"

        self.home = os.path.expanduser("~")
        self.root = "/"

        #Label+Entry for File Name
        self.filenameBox = Box(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        self.filenameBox.horizontal = True
        self.filenameBox.show()

        fileLabel = Label(self, size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                size_hint_align=FILL_HORIZ)
        fileLabel.text = "Filename:"
        fileLabel.show()

        self.fileEntry = Entry(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_HORIZ)
        self.fileEntry.single_line_set(True)
        self.fileEntry.scrollable_set(True)
        self.fileEntry.callback_changed_user_add(self.fileEntryChanged)
        self.fileEntry.show()

        self.filenameBox.pack_end(fileLabel)
        self.filenameBox.pack_end(self.fileEntry)

        sep = Separator(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        sep.horizontal_set(True)
        sep.show()

        #Label+Entry for File Path
        self.filepathBox = Box(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        self.filepathBox.horizontal = True
        self.filepathBox.show()

        fileLabel = Label(self, size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                size_hint_align=FILL_HORIZ)
        fileLabel.text = "Current Folder:"
        fileLabel.show()

        self.filepathEntry = Entry(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_HORIZ)
        self.filepathEntry.single_line_set(True)
        self.filepathEntry.scrollable_set(True)
        self.filepathEntry.callback_changed_user_add(self.fileEntryChanged)
        self.filepathEntry.callback_unfocused_add(self.filepathEditDone)
        self.filepathEntry.callback_activated_add(self.filepathEditDone)
        #Wish this worked. Doesn't seem to do anything
        #self.filepathEntry.input_hint_set(ELM_INPUT_HINT_AUTO_COMPLETE)

        if defaultPath and os.path.isdir(defaultPath):
            startPath = defaultPath
        else:
            startPath = self.home
        self.filepathEntry.show()

        self.filepathBox.pack_end(fileLabel)
        self.filepathBox.pack_end(self.filepathEntry)

        self.autocompleteHover = Hoversel(self, hover_parent=self)
        self.autocompleteHover.callback_selected_add(self.autocompleteSelected)
        #self.autocompleteHover.show()

        self.fileSelectorBox = Panes(self, content_left_size=0.3,
                      size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        self.fileSelectorBox.show()

        """Bookmarks Box contains:

            - Button - Up Arrow
            - List - Home/Root/GTK bookmarks
            - Box
            -- Button - Add Bookmark
            -- Button - Remove Bookmark"""
        self.bookmarkBox = Box(self, size_hint_weight=(0.3, EVAS_HINT_EXPAND),
                size_hint_align=FILL_BOTH)
        self.bookmarkBox.show()


        upIcon = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        upIcon.standard_set("go-up")
        upIcon.show()

        self.upButton = Button(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ, content=upIcon)
        self.upButton.text = "Up"
        self.upButton.callback_pressed_add(self.upButtonPressed)
        self.upButton.show()

        self.bookmarksList = List(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        self.bookmarksList.callback_activated_add(self.bookmarkDoubleClicked)
        self.bookmarksList.show()

        self.bookmarkModBox = Box(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        self.bookmarkModBox.horizontal = True
        self.bookmarkModBox.show()

        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("add")
        con.show()

        self.addButton = Button(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ, content=con)
        self.addButton.callback_pressed_add(self.addButtonPressed)
        self.addButton.disabled = True
        self.addButton.show()

        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("remove")
        con.show()

        self.removeButton = Button(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ, content=con)
        self.removeButton.callback_pressed_add(self.removeButtonPressed)
        self.removeButton.disabled = True
        self.removeButton.show()

        self.bookmarkModBox.pack_end(self.addButton)
        self.bookmarkModBox.pack_end(self.removeButton)

        self.bookmarkBox.pack_end(self.upButton)
        self.bookmarkBox.pack_end(self.bookmarksList)
        self.bookmarkBox.pack_end(self.bookmarkModBox)

        #Directory List
        self.fileListBox = Box(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        self.fileListBox.show()
        
        self.fileSortButton = Button(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        self.fileSortButton.text = u"⬆ Name"
        self.fileSortButton.callback_pressed_add(self.sortData)
        self.fileSortButton.show()
        
        self.fileList = Genlist(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH, homogeneous=True,
                mode=ELM_LIST_COMPRESS)
        self.fileList.callback_activated_add(self.fileDoubleClicked)
        self.fileList.show()
        
        self.previewImage = previewImage = Image(self)
        #previewImage.size_hint_weight = EXPAND_BOTH
        previewImage.size_hint_align = FILL_BOTH
        previewImage.show()
        
        self.fileListBox.pack_end(self.fileSortButton)
        self.fileListBox.pack_end(self.fileList)
        self.fileListBox.pack_end(self.previewImage)

        self.fileSelectorBox.part_content_set("left", self.bookmarkBox)
        self.fileSelectorBox.part_content_set("right", self.fileListBox)

        #Cancel and Save/Open button
        self.buttonBox = Box(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=(1.0, 0.5))
        self.buttonBox.horizontal = True
        self.buttonBox.show()

        self.actionIcon = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        self.actionIcon.standard_set("document-save")
        self.actionIcon.show()

        self.actionButton = Button(self, size_hint_weight=(0.0, 0.0),
                size_hint_align=(1.0, 0.5), content=self.actionIcon)
        self.actionButton.text = "Save  "
        self.actionButton.callback_pressed_add(self.actionButtonPressed)
        self.actionButton.show()

        cancelIcon = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        cancelIcon.standard_set("exit")
        cancelIcon.show()

        self.cancelButton = Button(self, size_hint_weight=(0.0, 0.0),
                size_hint_align=(1.0, 0.5), content=cancelIcon)
        self.cancelButton.text = "Cancel  "
        self.cancelButton.callback_pressed_add(self.cancelButtonPressed)
        self.cancelButton.show()

        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("gtk-find")
        con.show()

        self.toggleHiddenButton = Button(self, size_hint_weight=(0.0, 0.0),
                size_hint_align=(1.0, 0.5), content=con)
        self.toggleHiddenButton.text = "Toggle Hidden  "
        self.toggleHiddenButton.callback_pressed_add(self.toggleHiddenButtonPressed)
        self.toggleHiddenButton.show()
        
        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("folder-new")
        con.show()
        
        self.createFolderButton = Button(self, size_hint_weight=(0.0, 0.0),
                size_hint_align=(1.0, 0.5), content=con)
        self.createFolderButton.text = "Create Folder  "
        self.createFolderButton.callback_pressed_add(self.createFolderButtonPressed)
        self.createFolderButton.show()

        self.buttonBox.pack_end(self.createFolderButton)
        self.buttonBox.pack_end(self.toggleHiddenButton)
        self.buttonBox.pack_end(self.cancelButton)
        self.buttonBox.pack_end(self.actionButton)

        self.pack_end(self.filenameBox)
        self.pack_end(sep)
        self.pack_end(self.filepathBox)
        self.pack_end(self.autocompleteHover)
        self.pack_end(self.fileSelectorBox)
        self.pack_end(self.buttonBox)

        self.populateBookmarks()
        
        self.createPopup = Popup(self)
        self.createPopup.part_text_set("title,text", "Create Folder:")

        self.createEn = en = Entry(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        en.single_line_set(True)
        en.scrollable_set(True)
        en.show()
        
        self.createPopup.content = en

        bt = Button(self, text="Create")
        bt.callback_clicked_add(self.createFolder)
        self.createPopup.part_content_set("button1", bt)

        bt2 = Button(self, text="Cancel")
        bt2.callback_clicked_add(self.closePopup)
        self.createPopup.part_content_set("button2", bt2)

        if defaultPopulate:
            self.populateFiles(startPath)
class FileSelector(Box):
    '''FileSelector Class'''

    # pylint: disable=too-many-instance-attributes, too-many-statements
    def __init__(self,
                 parent_widget,
                 *args,
                 default_path='',
                 default_populate=True,
                 **kwargs):
        Box.__init__(self, parent_widget, *args, **kwargs)

        self.cancel_cb = None
        self.action_cb = None
        self.cb_dir_change = None

        self.threaded_fn = ThreadedFunction()
        # pylint: disable=c-extension-no-member
        self._timer = ecore.Timer(0.02, self.populate_file)

        # Watch key presses for ctrl+l to select entry
        parent_widget.elm_event_callback_add(self.cb_events)

        self.selected_dir = None
        self.show_hidden = False
        self.cur_dir = None
        self.focused_entry = None
        self.dir_only = False
        self.sort_reverse = False
        self.adding_hidden = False
        self.pending_files = deque()
        self.cur_subdirs = []
        self.cur_files = []

        # Mode should be 'save' or 'load'
        self.mode = 'save'

        self.home = os.path.expanduser('~')

        desktop = os.environ.get('XDG_DESKTOP_DIR')
        if desktop:
            self.desktop = desktop
        else:
            self.desktop = self.home + '/Desktop'

        self.root = '/'

        # Label+Entry for File Name
        self.filename_bx = Box(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.filename_bx.horizontal = True
        self.filename_bx.show()

        file_label = Label(self,
                           size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                           size_hint_align=FILL_HORIZ)
        file_label.text = 'Filename:'
        file_label.show()

        self.file_entry = Entry(self,
                                size_hint_weight=EXPAND_BOTH,
                                size_hint_align=FILL_HORIZ)
        self.file_entry.single_line_set(True)
        self.file_entry.scrollable_set(True)
        self.file_entry.callback_changed_user_add(self.cb_file_entry)
        self.file_entry.show()

        self.filename_bx.pack_end(file_label)
        self.filename_bx.pack_end(self.file_entry)

        sep = Separator(self,
                        size_hint_weight=EXPAND_HORIZ,
                        size_hint_align=FILL_HORIZ)
        sep.horizontal_set(True)
        sep.show()

        # Label+Entry for File Path
        self.filepath_bx = Box(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.filepath_bx.horizontal = True
        self.filepath_bx.show()

        file_label = Label(self,
                           size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                           size_hint_align=FILL_HORIZ)
        file_label.text = 'Current Folder:'
        file_label.show()

        self.filepath_en = Entry(self,
                                 size_hint_weight=EXPAND_BOTH,
                                 size_hint_align=FILL_HORIZ)
        self.filepath_en.single_line_set(True)
        self.filepath_en.scrollable_set(True)
        self.filepath_en.callback_changed_user_add(self.cb_file_entry)
        self.filepath_en.callback_unfocused_add(self.cb_filepath_en)
        self.filepath_en.callback_activated_add(self.cb_filepath_en)
        # Wish this worked. Doesn't seem to do anything
        # Working now EFL 1.22 ?
        self.filepath_en.input_hint_set(ELM_INPUT_HINT_AUTO_COMPLETE)

        if default_path and os.path.isdir(default_path):
            start = default_path
        else:
            start = self.home
        self.filepath_en.show()

        self.filepath_bx.pack_end(file_label)
        self.filepath_bx.pack_end(self.filepath_en)

        self.autocomplete_hover = Hoversel(self, hover_parent=self)
        self.autocomplete_hover.callback_selected_add(self.cb_hover)
        self.autocomplete_hover.show()

        self.file_selector_bx = Panes(self,
                                      content_left_size=0.3,
                                      size_hint_weight=EXPAND_BOTH,
                                      size_hint_align=FILL_BOTH)
        self.file_selector_bx.show()
        # Bookmarks Box contains:
        #
        # - Button - Up Arrow
        # - List - Home/Desktop/Root/GTK bookmarks
        # - Box
        # -- Button - Add Bookmark
        # -- Button - Remove Bookmark
        self.bookmark_bx = Box(self,
                               size_hint_weight=(0.3, EVAS_HINT_EXPAND),
                               size_hint_align=FILL_BOTH)
        self.bookmark_bx.show()

        up_ic = Icon(self,
                     size_hint_weight=EXPAND_BOTH,
                     size_hint_align=FILL_BOTH,
                     order_lookup=ELM_ICON_LOOKUP_THEME)
        up_ic.standard_set('arrow-up')
        up_ic.show()

        self.up_btn = Button(self,
                             size_hint_weight=EXPAND_HORIZ,
                             size_hint_align=FILL_HORIZ,
                             content=up_ic)
        self.up_btn.text = 'Up'
        self.up_btn.callback_pressed_add(self.cb_up_btn)
        self.up_btn.show()

        self.bookmarks_lst = List(self,
                                  size_hint_weight=EXPAND_BOTH,
                                  size_hint_align=FILL_BOTH)
        self.bookmarks_lst.callback_activated_add(self.cb_bookmarks_lst)
        self.bookmarks_lst.show()

        self.bookmark_modbox = Box(self,
                                   size_hint_weight=EXPAND_HORIZ,
                                   size_hint_align=FILL_HORIZ)
        self.bookmark_modbox.horizontal = True
        self.bookmark_modbox.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('list-add')
        con.show()

        self.add_btn = Button(self,
                              size_hint_weight=EXPAND_HORIZ,
                              size_hint_align=FILL_HORIZ,
                              content=con)
        self.add_btn.callback_pressed_add(self.cb_add_btn)
        self.add_btn.disabled = True
        self.add_btn.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('list-remove')
        con.show()

        self.rm_btn = Button(self,
                             size_hint_weight=EXPAND_HORIZ,
                             size_hint_align=FILL_HORIZ,
                             content=con)
        self.rm_btn.callback_pressed_add(self.cb_remove)
        self.rm_btn.disabled = True
        self.rm_btn.show()

        self.bookmark_modbox.pack_end(self.add_btn)
        self.bookmark_modbox.pack_end(self.rm_btn)

        self.bookmark_bx.pack_end(self.up_btn)
        self.bookmark_bx.pack_end(self.bookmarks_lst)
        self.bookmark_bx.pack_end(self.bookmark_modbox)

        # Directory List
        self.file_list_bx = Box(self,
                                size_hint_weight=EXPAND_BOTH,
                                size_hint_align=FILL_BOTH)
        self.file_list_bx.show()

        self.file_sort_btn = Button(self,
                                    size_hint_weight=EXPAND_HORIZ,
                                    size_hint_align=FILL_HORIZ)
        self.file_sort_btn.text = u'⬆ Name'
        self.file_sort_btn.callback_pressed_add(self.cb_sort)
        self.file_sort_btn.show()

        self.file_lst = Genlist(self,
                                size_hint_weight=EXPAND_BOTH,
                                size_hint_align=FILL_BOTH,
                                homogeneous=True,
                                mode=ELM_LIST_COMPRESS)
        self.file_lst.callback_activated_add(self.cb_file_lst)
        self.file_lst.show()

        self.preview = preview = Image(self)
        preview.size_hint_align = FILL_BOTH
        preview.show()

        self.file_list_bx.pack_end(self.file_sort_btn)
        self.file_list_bx.pack_end(self.file_lst)
        self.file_list_bx.pack_end(self.preview)

        self.file_selector_bx.part_content_set('left', self.bookmark_bx)
        self.file_selector_bx.part_content_set('right', self.file_list_bx)

        # Cancel and Save/Open button
        self.button_bx = Box(self,
                             size_hint_weight=EXPAND_HORIZ,
                             size_hint_align=(1.0, 0.5))
        self.button_bx.horizontal = True
        self.button_bx.show()

        self.action_ic = Icon(self,
                              size_hint_weight=EXPAND_BOTH,
                              size_hint_align=FILL_BOTH)
        self.action_ic.standard_set('document-save')
        self.action_ic.show()

        self.action_btn = Button(self,
                                 size_hint_weight=(0.0, 0.0),
                                 size_hint_align=(1.0, 0.5),
                                 content=self.action_ic)
        self.action_btn.text = 'Save  '
        self.action_btn.callback_pressed_add(self.cb_action_btn)
        self.action_btn.show()

        cancel_ic = Icon(self,
                         size_hint_weight=EXPAND_BOTH,
                         size_hint_align=FILL_BOTH)
        cancel_ic.standard_set('application-exit')
        cancel_ic.show()

        self.cancel_btn = Button(self,
                                 size_hint_weight=(0.0, 0.0),
                                 size_hint_align=(1.0, 0.5),
                                 content=cancel_ic)
        self.cancel_btn.text = 'Cancel  '
        self.cancel_btn.callback_pressed_add(self.cb_cancel_btn)
        self.cancel_btn.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('edit-find')
        con.show()

        self.hidden_btn = Button(self,
                                 size_hint_weight=(0.0, 0.0),
                                 size_hint_align=(1.0, 0.5),
                                 content=con)
        self.hidden_btn.text = 'Toggle Hidden  '
        self.hidden_btn.callback_pressed_add(self.cb_toggle_hidden)
        self.hidden_btn.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('folder-new')
        con.show()

        self.create_dir_btn = Button(self,
                                     size_hint_weight=(0.0, 0.0),
                                     size_hint_align=(1.0, 0.5),
                                     content=con)
        self.create_dir_btn.text = 'Create Folder  '
        self.create_dir_btn.callback_pressed_add(self.cb_create_dir)
        self.create_dir_btn.show()

        self.button_bx.pack_end(self.create_dir_btn)
        self.button_bx.pack_end(self.hidden_btn)
        self.button_bx.pack_end(self.cancel_btn)
        self.button_bx.pack_end(self.action_btn)

        self.pack_end(self.filename_bx)
        self.pack_end(sep)
        self.pack_end(self.filepath_bx)
        self.pack_end(self.autocomplete_hover)
        self.pack_end(self.file_selector_bx)
        self.pack_end(self.button_bx)

        self.populate_bookmarks()

        self.create_popup = Popup(self)
        self.create_popup.part_text_set('title,text', 'Create Folder:')

        self.create_en = Entry(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.create_en.single_line_set(True)
        self.create_en.scrollable_set(True)
        self.create_en.show()

        self.create_popup.content = self.create_en

        bt0 = Button(self, text='Create')
        bt0.callback_clicked_add(self.cb_create_folder)
        self.create_popup.part_content_set('button1', bt0)
        bt1 = Button(self, text='Cancel')
        bt1.callback_clicked_add(self.cb_close_popup)
        self.create_popup.part_content_set('button2', bt1)

        self.recent = None  # keeps pylint happy:
        if default_populate:
            self.populate_files(start)

    def dir_only_set(self, value):
        '''Set folder only attribute and adjust display'''
        self.dir_only = value

        if not self.dir_only:
            self.filename_bx.show()
        else:
            self.filename_bx.hide()

    def cb_create_folder(self, obj):
        '''Create a new folder'''
        new = f'{self.cur_dir}{self.create_en.text}'
        os.makedirs(new)
        self.cb_close_popup()
        self.populate_files(self.cur_dir)

    def cb_create_dir(self, obj):
        '''Open popup to create a new folder'''
        self.create_en.text = ''
        self.create_popup.show()
        self.create_en.select_all()

    def cb_close_popup(self, btn=None):
        '''Close popup'''
        self.create_popup.hide()

    # pylint: disable=unused-argument
    def shutdown(self, obj=None):
        '''Cleanup function for FileSelector widget shutdown'''
        self._timer.delete()
        self.threaded_fn.shutdown()

    def cb_sort(self, btn):
        '''callback for sort button'''
        self.sort_reverse = not self.sort_reverse
        if self.sort_reverse:
            self.file_sort_btn.text = u'⬇ Name'
        else:
            self.file_sort_btn.text = u'⬆ Name'

        self.populate_files(self.cur_dir)

    def populate_bookmarks(self):
        '''Fill Bookamrks List'''
        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('document-open-recent')
        con.show()
        cur_item = self.bookmarks_lst.item_append('Recent', icon=con)
        cur_item.data['path'] = 'recent:///'

        cur_item = self.bookmarks_lst.item_append('')
        cur_item.separator_set(True)

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('user-home')
        con.show()

        cur_item = self.bookmarks_lst.item_append('Home', icon=con)
        cur_item.data['path'] = self.home

        if os.path.isdir(self.desktop):
            con = Icon(self,
                       size_hint_weight=EXPAND_BOTH,
                       size_hint_align=FILL_BOTH)
            con.standard_set('user-desktop')
            con.show()

            cur_item = self.bookmarks_lst.item_append('Desktop', icon=con)
            cur_item.data['path'] = self.desktop

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('drive-harddisk')
        con.show()

        cur_item = self.bookmarks_lst.item_append('Root', icon=con)
        cur_item.data['path'] = self.root

        cur_item = self.bookmarks_lst.item_append('')
        cur_item.separator_set(True)

        for url in self.get_gtk_bookmarks():
            con = Icon(self,
                       size_hint_weight=EXPAND_BOTH,
                       size_hint_align=FILL_BOTH)
            con.standard_set('folder')
            con.show()
            cur_item = self.bookmarks_lst.item_append(url.split('/')[-1],
                                                      icon=con)
            cur_item.data['path'] = url[7:]

    def populate_file(self):
        '''Add Pending File to Files list'''
        pen_file = len(self.pending_files)
        if pen_file:
            for _ in range(int(math.sqrt(pen_file))):
                path, name, is_dir = self.pending_files.popleft()
                self.pack_all(path, name, is_dir)

        # else:
        #    self._timer.freeze()

        return True

    def populate_files(self, path):
        '''Start threaded FN to get dir contents'''
        self.autocomplete_hover.hover_end()

        self.pending_files.clear()

        if path[:-1] != '/':
            path = path + '/'
        if path != self.filepath_en.text or not self.show_hidden:
            self.adding_hidden = False

            if self.cb_dir_change:
                self.cb_dir_change(path)

            del self.cur_subdirs[:]
            del self.cur_files[:]
            self.file_lst.clear()
        else:
            self.adding_hidden = True

        self.filepath_en.text = path.replace('//', '/')
        self.cur_dir = path.replace('//', '/')

        self.threaded_fn.run(self.get_dir_contents)

    def get_dir_contents(self):
        '''Add Folder contents to pending files'''
        path = self.cur_dir
        if path == 'recent://':
            self.recent = Bookmarks()
            data = list(self.recent.dict.keys())
            for cur in data:
                self.pending_files.append([path, cur, False])
            return
        data = os.listdir(str(path))

        sorted_data = []
        for name in data:
            is_dir = os.path.isdir(f'{path}{name}')
            if is_dir:
                self.cur_subdirs.append(name)
                if self.sort_reverse:
                    sorted_data.append([1, name])
                else:
                    sorted_data.append([0, name])
            else:
                self.cur_files.append(name)
                if self.sort_reverse:
                    sorted_data.append([0, name])
                else:
                    sorted_data.append([1, name])

        sorted_data.sort(reverse=self.sort_reverse)
        for cur in sorted_data:
            name = cur[1]
            is_dir = cur[0] if self.sort_reverse else not cur[0]
            if self.adding_hidden and name[0] == '.':
                self.pending_files.append([path, name, is_dir])
            elif (name[0] != '.' or
                  self.show_hidden) and not self.adding_hidden:
                self.pending_files.append([path, name, is_dir])

    def pack_all(self, path, name, is_dir):
        '''Append to genlist'''
        if is_dir:
            gen_lst_it = GenlistItem(item_data={
                'type': 'dir',
                'path': path,
                'd': name
            },
                                     item_class=DIRGLIC,
                                     func=self.list_it_selected)
        else:
            gen_lst_it = GenlistItem(item_data={
                'type': 'file',
                'path': path,
                'd': name
            },
                                     item_class=FILEGLIC,
                                     func=self.list_it_selected)
        gen_lst_it.append_to(self.file_lst)

    def cb_file_lst(self, obj, item=None, event=None):
        '''File list double clicked callback'''
        if item.data['type'] == 'dir':
            self.add_btn.disabled = True
            self.rm_btn.disabled = True
            self.populate_files(item.data['path'] + item.text)
        else:
            self.cb_action_btn(self.action_btn)

    # pylint: disable=no-self-use
    def get_gtk_bookmarks(self):
        '''Read GTK bookmarks'''
        try:
            with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'),
                      'r') as gtk_bk:
                bks = []
                for url in gtk_bk:
                    url = url.split(' ')[0]
                    url = url.replace('%20', ' ')
                    url = url.strip()
                    bks.append(url)
                return bks
        except IOError:
            return []

    def cb_bookmarks_lst(self, obj, item=None, event=None):
        '''Bookamrk list item double clicked callback'''
        item.selected_set(False)
        self.add_btn.disabled = True
        self.rm_btn.disabled = True
        self.populate_files(item.data['path'])

    def list_it_selected(self, item, gen_lst, data):
        '''Genlist item selected'''
        if item.data['type'] == 'dir':
            self.dir_selected(item)
        else:
            self.file_selected(item.text)
            item.selected_set(False)

    def file_selected(self, cur):
        '''File was selected, update everything'''
        self.file_entry.text = cur
        self.add_btn.disabled = True
        self.rm_btn.disabled = True
        self.selected_dir = None

        # Update image preview if an image is selected
        if cur[-3:] in ['jpg', 'png', 'gif']:
            if self.filepath_en.text == 'recent://':
                self.preview.file_set(self.recent[cur])
            else:
                self.preview.file_set(f'{self.filepath_en.text}/{cur}')
            self.preview.size_hint_weight = (1.0, 0.4)
        else:
            self.preview.size_hint_weight = (0, 0)

    def dir_selected(self, btn):
        '''Folder was selected, update everything'''
        cur = btn.data['path']
        if btn == self.selected_dir:
            self.populate_files(cur)
            self.add_btn.disabled = True
        else:
            self.selected_dir = btn
            gtk_bks = self.get_gtk_bookmarks()
            to_append = f'file://{self.filepath_en.text}{self.selected_dir.text}'
            if to_append not in gtk_bks:
                self.add_btn.disabled = False
                self.rm_btn.disabled = True
            else:
                self.add_btn.disabled = True
                self.rm_btn.disabled = False

    def cb_up_btn(self, btn):
        '''Callback for dir up button'''
        cur = self.filepath_en.text.split('/')
        del cur[-1]
        del cur[-1]
        self.populate_files('/'.join(cur))

    def cb_add_btn(self, btn):
        '''Add dir button pressed'''
        safe = self.selected_dir.text.replace(' ', '%20')
        cur = f"file://{self.filepath_en.text}{safe}"

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set('gtk-directory')
        con.show()
        current = self.bookmarks_lst.item_append(self.selected_dir.text,
                                                 icon=con)
        current.data[
            'path'] = f'{self.filepath_en.text}{self.selected_dir.text}'
        self.bookmarks_lst.go()

        self.add_btn.disabled = True
        self.rm_btn.disabled = False

        with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'),
                  'a') as gtk_bk:
            gtk_bk.write(cur + ' ' + self.selected_dir.text + '\n')

    def cb_remove(self, btn):
        '''Remove button pressed callback'''
        cur = f'file://{self.filepath_en.text}{self.selected_dir.text}'
        bks = self.get_gtk_bookmarks()
        bks.remove(cur)

        with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'),
                  'w') as gtk_bk:
            for url in bks:
                name = url.split('/')[-1]
                url = url.replace(' ', '%20')
                gtk_bk.write(url + ' ' + name + '\n')

        self.bookmarks_lst.clear()
        self.populate_bookmarks()

        self.add_btn.disabled = False
        self.rm_btn.disabled = True

    def set_mode(self, mode):
        '''Set FileSelector mode: save or open'''
        self.mode = mode.lower()
        self.action_btn.text = f'{mode}  '
        self.action_ic.standard_set(f'document-{mode.lower()}')

        if self.mode != 'save':
            self.create_dir_btn.hide()
        else:
            self.create_dir_btn.show()

    def cb_events(self, obj, src, event_type, event):
        '''Keyboard event callback: Watch key presses for ctrl+l to select entry'''
        if event.modifier_is_set(
                'Control') and event_type == EVAS_CALLBACK_KEY_DOWN:
            if event.key.lower() == 'l':
                self.filepath_en.focus_set(True)
                self.filepath_en.cursor_end_set()

    def cb_toggle_hidden(self, btn):
        '''Toggle hidden files and folders'''
        self.show_hidden = not self.show_hidden
        self.populate_files(self.filepath_en.text)

    def callback_cancel_add(self, callback):
        '''Add a cancel callback'''
        self.cancel_cb = callback

    def callback_activated_add(self, callback):
        '''Add an action callback'''
        self.action_cb = callback

    def callback_directory_open_add(self, callback):
        '''Add an open folder callback'''
        self.cb_dir_change = callback

    def cb_cancel_btn(self, btn):
        '''Cancel button callback'''
        if self.cancel_cb:
            self.cancel_cb(self)

    def cb_action_btn(self, btn):
        '''Action button callback'''
        if self.action_cb:
            if not self.dir_only and self.file_entry.text:
                if self.filepath_en.text == 'recent://':
                    self.action_cb(self, self.recent[self.file_entry.text])
                else:
                    self.action_cb(
                        self, f'{self.filepath_en.text}{self.file_entry.text}')
            elif self.dir_only:
                self.action_cb(self, f'{self.filepath_en.text}')

    def cb_file_entry(self, entry):
        '''File entry callback'''
        typed = entry.text.split('/')[-1]
        new_lst = []
        self.focused_entry = entry
        if entry == self.filepath_en:
            for name in self.cur_subdirs:
                if typed in name:
                    if len(new_lst) < 10:
                        new_lst.append(name)
                    else:
                        break
        else:
            for name in self.cur_files:
                if typed in name:
                    if len(new_lst) < 10:
                        new_lst.append(name)
                    else:
                        break

        if self.autocomplete_hover.expanded_get():
            self.autocomplete_hover.hover_end()
        self.autocomplete_hover.clear()

        for name in new_lst:
            self.autocomplete_hover.item_add(name)

        self.autocomplete_hover.hover_begin()
        self.focused_entry.focus = True

    def cb_hover(self, hov, item):
        '''Autocomplete Hover item selected callback'''
        hov.hover_end()
        if self.focused_entry == self.filepath_en:
            self.populate_files(f'{self.cur_dir}{item.text}')
            self.filepath_en.cursor_end_set()
        else:
            self.file_entry.text = item.text
            self.file_entry.cursor_end_set()

    def cb_filepath_en(self, entry):
        '''File Path Entry callback'''
        if os.path.isdir(entry.text) and entry.text != self.cur_dir:
            self.populate_files(entry.text)
            self.filepath_en.cursor_end_set()
        else:
            # entry.text = self.cur_dir
            pass

    def selected_get(self):
        '''Return selected'''
        return f'{self.filepath_en.text}{self.file_entry.text}'
class FileSelector(Box):
    def __init__(self, parent_widget, defaultPath="", defaultPopulate=True, *args, **kwargs):
        Box.__init__(self, parent_widget, *args, **kwargs)

        self.cancelCallback = None
        self.actionCallback = None
        self.directoryChangeCallback = None
        
        self.threadedFunction = ThreadedFunction()
        self._timer = ecore.Timer(0.02, self.populateFile)

        #Watch key presses for ctrl+l to select entry
        parent_widget.elm_event_callback_add(self.eventsCb)

        self.selectedFolder = None
        self.showHidden = False
        self.currentDirectory = None
        self.focusedEntry = None
        self.folderOnly = False
        self.sortReverse = False
        self.addingHidden = False
        self.pendingFiles = deque()
        self.currentSubFolders = []
        self.currentFiles = []

        #Mode should be "save" or "load"
        self.mode = "save"

        self.home = os.path.expanduser("~")
        self.root = "/"

        #Label+Entry for File Name
        self.filenameBox = Box(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        self.filenameBox.horizontal = True
        self.filenameBox.show()

        fileLabel = Label(self, size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                size_hint_align=FILL_HORIZ)
        fileLabel.text = "Filename:"
        fileLabel.show()

        self.fileEntry = Entry(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_HORIZ)
        self.fileEntry.single_line_set(True)
        self.fileEntry.scrollable_set(True)
        self.fileEntry.callback_changed_user_add(self.fileEntryChanged)
        self.fileEntry.show()

        self.filenameBox.pack_end(fileLabel)
        self.filenameBox.pack_end(self.fileEntry)

        sep = Separator(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        sep.horizontal_set(True)
        sep.show()

        #Label+Entry for File Path
        self.filepathBox = Box(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        self.filepathBox.horizontal = True
        self.filepathBox.show()

        fileLabel = Label(self, size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                size_hint_align=FILL_HORIZ)
        fileLabel.text = "Current Folder:"
        fileLabel.show()

        self.filepathEntry = Entry(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_HORIZ)
        self.filepathEntry.single_line_set(True)
        self.filepathEntry.scrollable_set(True)
        self.filepathEntry.callback_changed_user_add(self.fileEntryChanged)
        self.filepathEntry.callback_unfocused_add(self.filepathEditDone)
        self.filepathEntry.callback_activated_add(self.filepathEditDone)
        #Wish this worked. Doesn't seem to do anything
        #self.filepathEntry.input_hint_set(ELM_INPUT_HINT_AUTO_COMPLETE)

        if defaultPath and os.path.isdir(defaultPath):
            startPath = defaultPath
        else:
            startPath = self.home
        self.filepathEntry.show()

        self.filepathBox.pack_end(fileLabel)
        self.filepathBox.pack_end(self.filepathEntry)

        self.autocompleteHover = Hoversel(self, hover_parent=self)
        self.autocompleteHover.callback_selected_add(self.autocompleteSelected)
        #self.autocompleteHover.show()

        self.fileSelectorBox = Panes(self, content_left_size=0.3,
                      size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        self.fileSelectorBox.show()

        """Bookmarks Box contains:

            - Button - Up Arrow
            - List - Home/Root/GTK bookmarks
            - Box
            -- Button - Add Bookmark
            -- Button - Remove Bookmark"""
        self.bookmarkBox = Box(self, size_hint_weight=(0.3, EVAS_HINT_EXPAND),
                size_hint_align=FILL_BOTH)
        self.bookmarkBox.show()


        upIcon = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        upIcon.standard_set("go-up")
        upIcon.show()

        self.upButton = Button(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ, content=upIcon)
        self.upButton.text = "Up"
        self.upButton.callback_pressed_add(self.upButtonPressed)
        self.upButton.show()

        self.bookmarksList = List(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        self.bookmarksList.callback_activated_add(self.bookmarkDoubleClicked)
        self.bookmarksList.show()

        self.bookmarkModBox = Box(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        self.bookmarkModBox.horizontal = True
        self.bookmarkModBox.show()

        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("add")
        con.show()

        self.addButton = Button(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ, content=con)
        self.addButton.callback_pressed_add(self.addButtonPressed)
        self.addButton.disabled = True
        self.addButton.show()

        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("remove")
        con.show()

        self.removeButton = Button(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ, content=con)
        self.removeButton.callback_pressed_add(self.removeButtonPressed)
        self.removeButton.disabled = True
        self.removeButton.show()

        self.bookmarkModBox.pack_end(self.addButton)
        self.bookmarkModBox.pack_end(self.removeButton)

        self.bookmarkBox.pack_end(self.upButton)
        self.bookmarkBox.pack_end(self.bookmarksList)
        self.bookmarkBox.pack_end(self.bookmarkModBox)

        #Directory List
        self.fileListBox = Box(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        self.fileListBox.show()
        
        self.fileSortButton = Button(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        self.fileSortButton.text = u"⬆ Name"
        self.fileSortButton.callback_pressed_add(self.sortData)
        self.fileSortButton.show()
        
        self.fileList = Genlist(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH, homogeneous=True,
                mode=ELM_LIST_COMPRESS)
        self.fileList.callback_activated_add(self.fileDoubleClicked)
        self.fileList.show()
        
        self.previewImage = previewImage = Image(self)
        #previewImage.size_hint_weight = EXPAND_BOTH
        previewImage.size_hint_align = FILL_BOTH
        previewImage.show()
        
        self.fileListBox.pack_end(self.fileSortButton)
        self.fileListBox.pack_end(self.fileList)
        self.fileListBox.pack_end(self.previewImage)

        self.fileSelectorBox.part_content_set("left", self.bookmarkBox)
        self.fileSelectorBox.part_content_set("right", self.fileListBox)

        #Cancel and Save/Open button
        self.buttonBox = Box(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=(1.0, 0.5))
        self.buttonBox.horizontal = True
        self.buttonBox.show()

        self.actionIcon = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        self.actionIcon.standard_set("document-save")
        self.actionIcon.show()

        self.actionButton = Button(self, size_hint_weight=(0.0, 0.0),
                size_hint_align=(1.0, 0.5), content=self.actionIcon)
        self.actionButton.text = "Save  "
        self.actionButton.callback_pressed_add(self.actionButtonPressed)
        self.actionButton.show()

        cancelIcon = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        cancelIcon.standard_set("exit")
        cancelIcon.show()

        self.cancelButton = Button(self, size_hint_weight=(0.0, 0.0),
                size_hint_align=(1.0, 0.5), content=cancelIcon)
        self.cancelButton.text = "Cancel  "
        self.cancelButton.callback_pressed_add(self.cancelButtonPressed)
        self.cancelButton.show()

        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("gtk-find")
        con.show()

        self.toggleHiddenButton = Button(self, size_hint_weight=(0.0, 0.0),
                size_hint_align=(1.0, 0.5), content=con)
        self.toggleHiddenButton.text = "Toggle Hidden  "
        self.toggleHiddenButton.callback_pressed_add(self.toggleHiddenButtonPressed)
        self.toggleHiddenButton.show()
        
        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("folder-new")
        con.show()
        
        self.createFolderButton = Button(self, size_hint_weight=(0.0, 0.0),
                size_hint_align=(1.0, 0.5), content=con)
        self.createFolderButton.text = "Create Folder  "
        self.createFolderButton.callback_pressed_add(self.createFolderButtonPressed)
        self.createFolderButton.show()

        self.buttonBox.pack_end(self.createFolderButton)
        self.buttonBox.pack_end(self.toggleHiddenButton)
        self.buttonBox.pack_end(self.cancelButton)
        self.buttonBox.pack_end(self.actionButton)

        self.pack_end(self.filenameBox)
        self.pack_end(sep)
        self.pack_end(self.filepathBox)
        self.pack_end(self.autocompleteHover)
        self.pack_end(self.fileSelectorBox)
        self.pack_end(self.buttonBox)

        self.populateBookmarks()
        
        self.createPopup = Popup(self)
        self.createPopup.part_text_set("title,text", "Create Folder:")

        self.createEn = en = Entry(self, size_hint_weight=EXPAND_HORIZ,
                size_hint_align=FILL_HORIZ)
        en.single_line_set(True)
        en.scrollable_set(True)
        en.show()
        
        self.createPopup.content = en

        bt = Button(self, text="Create")
        bt.callback_clicked_add(self.createFolder)
        self.createPopup.part_content_set("button1", bt)

        bt2 = Button(self, text="Cancel")
        bt2.callback_clicked_add(self.closePopup)
        self.createPopup.part_content_set("button2", bt2)

        if defaultPopulate:
            self.populateFiles(startPath)

    def folderOnlySet(self, ourValue):
        self.folderOnly = ourValue
        
        if not self.folderOnly:
            self.filenameBox.show()
        else:
            self.filenameBox.hide()

    def createFolder(self, obj):
        newDir = "%s%s"%(self.currentDirectory, self.createEn.text)
        os.makedirs(newDir)
        self.closePopup()
        self.populateFiles(self.currentDirectory)

    def createFolderButtonPressed(self, obj):
        self.createEn.text = ""
        self.createPopup.show()
        self.createEn.select_all()
    
    def closePopup(self, btn=None):
        self.createPopup.hide()

    def shutdown(self, obj=None):
        self._timer.delete()
        self.threadedFunction.shutdown()

    def sortData(self, btn):
        self.sortReverse = not self.sortReverse
        
        if self.sortReverse:
            self.fileSortButton.text = u"⬇ Name"
        else:
            self.fileSortButton.text = u"⬆ Name"
        
        self.populateFiles(self.currentDirectory)

    def populateBookmarks(self):
        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("folder_home")
        con.show()

        it = self.bookmarksList.item_append("Home", icon=con)
        it.data["path"] = self.home

        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                size_hint_align=FILL_BOTH)
        con.standard_set("drive-harddisk")
        con.show()

        it = self.bookmarksList.item_append("Root", icon=con)
        it.data["path"] = self.root

        it = self.bookmarksList.item_append("")
        it.separator_set(True)

        for bk in self.getGTKBookmarks():
            con = Icon(self, size_hint_weight=EXPAND_BOTH,
                    size_hint_align=FILL_BOTH)
            con.standard_set("gtk-directory")
            con.show()
            it = self.bookmarksList.item_append(bk.split("/")[-1], icon=con)
            it.data["path"] = bk[7:]

    def populateFile(self):
        pen_file = len(self.pendingFiles)
        if pen_file:
            for _ in range(int(math.sqrt(pen_file))):
                ourPath, d, isDir = self.pendingFiles.popleft()
                self.packFileFolder(ourPath, d, isDir)

        #else:
        #    self._timer.freeze()
        
        return True

    def populateFiles(self, ourPath):
        self.autocompleteHover.hover_end()

        self.pendingFiles.clear()

        if ourPath[:-1] != "/":
            ourPath = ourPath + "/"

        if ourPath != self.filepathEntry.text or not self.showHidden:
            self.addingHidden = False

            if self.directoryChangeCallback:
                self.directoryChangeCallback(ourPath)

            del self.currentSubFolders[:]
            del self.currentFiles[:]
            self.fileList.clear()
        else:
            self.addingHidden = True

        self.filepathEntry.text = ourPath.replace("//", "/")
        self.currentDirectory = ourPath.replace("//", "/")
    
        self.threadedFunction.run(self.getFolderContents)
        #self._timer.thaw()
    
    def getFolderContents(self):
        ourPath = self.currentDirectory
        
        try:
            data = os.listdir(unicode(ourPath))
        except:
            data = os.listdir(str(ourPath))
        
        sortedData = []

        for d in data:
            isDir = os.path.isdir("%s%s"%(ourPath, d))

            if isDir:
                self.currentSubFolders.append(d)
                if self.sortReverse:
                    sortedData.append([1, d])
                else:
                    sortedData.append([0, d])
            else:
                self.currentFiles.append(d)
                if self.sortReverse:
                    sortedData.append([0, d])
                else:
                    sortedData.append([1, d])

        sortedData.sort(reverse=self.sortReverse)
        
        for ourFile in sortedData:
            d = ourFile[1]
            isDir = ourFile[0] if self.sortReverse else not ourFile[0]
            if self.addingHidden and d[0] == ".":
                self.pendingFiles.append([ourPath, d, isDir])
            elif (d[0] != "." or self.showHidden) and not self.addingHidden:
                self.pendingFiles.append([ourPath, d, isDir])

    def packFileFolder(self, ourPath, d, isDir):
        if isDir:
            li = GenlistItem(item_data={"type": "dir", "path": ourPath, "d": d}, item_class=dirglic, func=self.listItemSelected)
        else:
            li = GenlistItem(item_data={"type": "file", "path": ourPath, "d": d}, item_class=fileglic, func=self.listItemSelected)
            
        li.append_to(self.fileList)
        #self.fileList.go()
        #print("Adding: %s %s %s"%(ourPath, d, isDir))

    def fileDoubleClicked(self, obj, item=None, eventData=None):
        if item.data["type"] == "dir":
            self.addButton.disabled = True
            self.removeButton.disabled = True
            self.populateFiles(item.data["path"]+item.text)
        else:
            self.actionButtonPressed(self.actionButton)

    def getGTKBookmarks(self):
        try:
            with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'),'r') as f:
                ourBks = []
                for x in f:
                    x = x.split(" ")[0]
                    x = x.replace("%20", " ")
                    x = x.strip()
                    ourBks.append(x)
                return ourBks
        except IOError:
            return []

    def bookmarkDoubleClicked(self, obj, item=None, eventData=None):
        item.selected_set(False)
        self.addButton.disabled = True
        self.removeButton.disabled = True
        self.populateFiles(item.data["path"])

    def listItemSelected(self, item, gl, data):
        if item.data["type"] == "dir":
            self.directorySelected(item)
        else:
            self.fileSelected(item.text)
            item.selected_set(False)

    def fileSelected(self, ourFile):
        self.fileEntry.text = ourFile
        self.addButton.disabled = True
        self.removeButton.disabled = True
        self.selectedFolder = None
        
        #Update image preview if an image is selected
        if ourFile[-3:] in ["jpg", "png", "gif"]:
            self.previewImage.file_set("%s/%s"%(self.filepathEntry.text, ourFile))
            self.previewImage.size_hint_weight = (1.0, 0.4)
        else:
            self.previewImage.size_hint_weight = (0, 0)

    def directorySelected(self, btn):
        ourPath = btn.data["path"]
        if btn == self.selectedFolder:
            self.populateFiles(ourPath)
            self.addButton.disabled = True
        else:
            self.selectedFolder = btn

            currentMarks = self.getGTKBookmarks()

            toAppend = "file://%s%s"%(self.filepathEntry.text, self.selectedFolder.text)

            if toAppend not in currentMarks:
                self.addButton.disabled = False
                self.removeButton.disabled = True
            else:
                self.addButton.disabled = True
                self.removeButton.disabled = False

    def upButtonPressed(self, btn):
        ourSplit = self.filepathEntry.text.split("/")
        del ourSplit[-1]
        del ourSplit[-1]
        self.populateFiles("/".join(ourSplit))

    def addButtonPressed(self, btn):
        toAppend = "file://%s%s"%(self.filepathEntry.text, self.selectedFolder.text.replace(" ", "%20"))

        con = Icon(self, size_hint_weight=EXPAND_BOTH,
                    size_hint_align=FILL_BOTH)
        con.standard_set("gtk-directory")
        con.show()
        it = self.bookmarksList.item_append(self.selectedFolder.text, icon=con)
        it.data["path"] = "%s%s"%(self.filepathEntry.text, self.selectedFolder.text)

        self.bookmarksList.go()

        self.addButton.disabled = True
        self.removeButton.disabled = False

        with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'),'a') as f:
                f.write( toAppend + " " + self.selectedFolder.text + "\n" )

    def removeButtonPressed(self, btn):
        toRemove = "file://%s%s"%(self.filepathEntry.text, self.selectedFolder.text)

        bks = self.getGTKBookmarks()
        bks.remove(toRemove)

        with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'),'w') as f:
            for b in bks:
                bName = b.split("/")[-1]
                b = b.replace(" ", "%20")
                f.write( b + " " + bName + "\n" )

        self.bookmarksList.clear()
        self.populateBookmarks()

        self.addButton.disabled = False
        self.removeButton.disabled = True

    def setMode(self, ourMode):
        self.mode = ourMode.lower()

        self.actionButton.text = "%s  "%ourMode
        self.actionIcon.standard_set("document-%s"%ourMode.lower())
        
        if self.mode != "save":
            self.createFolderButton.hide()
        else:
            self.createFolderButton.show()

    def eventsCb(self, obj, src, event_type, event):
        if event.modifier_is_set("Control") and event_type == EVAS_CALLBACK_KEY_DOWN:
            if event.key.lower() == "l":
                self.filepathEntry.focus_set(True)
                self.filepathEntry.cursor_end_set()

    def toggleHiddenButtonPressed(self, btn):
        self.showHidden = not self.showHidden
        self.populateFiles(self.filepathEntry.text)
        
    def toggleHidden(self):
        self.showHidden = not self.showHidden
        self.populateFiles(self.filepathEntry.text)

    def callback_cancel_add(self, cb):
        self.cancelCallback = cb

    def callback_activated_add(self, cb):
        self.actionCallback = cb

    def callback_directory_open_add(self, cb):
        self.directoryChangeCallback = cb

    def cancelButtonPressed(self, btn):
        if self.cancelCallback:
            self.cancelCallback(self)

    def actionButtonPressed(self, btn):
        if self.actionCallback:
            if not self.folderOnly and self.fileEntry.text:
                self.actionCallback(self, "%s%s"%(self.filepathEntry.text, self.fileEntry.text))
            elif self.folderOnly:
                self.actionCallback(self, "%s"%(self.filepathEntry.text))

    def fileEntryChanged(self, en):
        typed = en.text.split("/")[-1]

        newList = []

        self.focusedEntry = en

        if en == self.filepathEntry:
            for x in self.currentSubFolders:
                if typed in x:
                    if len(newList) < 10:
                        newList.append(x)
                    else:
                        break
        else:
            for x in self.currentFiles:
                if typed in x:
                    if len(newList) < 10:
                        newList.append(x)
                    else:
                        break

        if self.autocompleteHover.expanded_get():
            self.autocompleteHover.hover_end()

        self.autocompleteHover.clear()

        for x in newList:
            self.autocompleteHover.item_add(x)

        self.autocompleteHover.hover_begin()

    def autocompleteSelected(self, hov, item):
        hov.hover_end()
        if self.focusedEntry == self.filepathEntry:
            self.populateFiles("%s%s"%(self.currentDirectory, item.text))
            self.filepathEntry.cursor_end_set()
        else:
            self.fileEntry.text = item.text
            self.fileEntry.cursor_end_set()

    def filepathEditDone(self, en):
        if os.path.isdir(en.text) and en.text != self.currentDirectory:
            self.populateFiles(en.text)
            self.filepathEntry.cursor_end_set()
        else:
            #en.text = self.currentDirectory
            pass
    
    def selected_get(self):
        return "%s%s"%(self.filepathEntry.text, self.fileEntry.text)
Exemple #12
0
    def __init__(self):
        self.repo = None
        self.branch_selector = None
        self.caption_label = None
        self.status_label = None
        self.graph = None
        self.diff_view = None

        StandardWindow.__init__(self, "egitu", "Efl GIT gUi - Egitu")
        self.autodel_set(True)
        self.callback_delete_request_add(lambda o: elm.exit())

        # main vertical box
        box = Box(self, size_hint_weight = EXPAND_BOTH)
        self.resize_object_add(box)
        box.show()

        # header
        fr = Frame(self, style="outdent_bottom", size_hint_weight=EXPAND_HORIZ,
                   size_hint_align=FILL_BOTH)
        box.pack_end(fr)
        fr.show()

        tb = Table(self, size_hint_weight=EXPAND_HORIZ,
                  size_hint_align=FILL_BOTH)
        fr.content = tb
        tb.show()

        # main menu button
        bt = Button(self, text='Menu')
        bt.content = Icon(self, standard='home')
        bt.callback_clicked_add(lambda b: EgituMenu(self, b))
        tb.pack(bt, 0, 0, 1, 1)
        bt.show()

        # editable description entry
        self.caption_label = EditableDescription(self)
        tb.pack(self.caption_label, 1, 0, 1, 1)
        self.caption_label.show()

        # branch selector
        lb = Label(self, text='On branch')
        tb.pack(lb, 2, 0, 1, 1)
        lb.show()

        self.branch_selector = Hoversel(self, text='none')
        self.branch_selector.callback_selected_add(self.branch_selected_cb)
        tb.pack(self.branch_selector, 3, 0, 1, 1)
        self.branch_selector.show()

        # status label + button
        self.status_label = lb = Entry(self, single_line=True, editable=False)
        tb.pack(lb, 4, 0, 1, 1)
        lb.show()

        ### Main content (left + right panes)
        panes = Panes(self, content_left_size = 0.5,
                       size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        box.pack_end(panes)
        panes.show()

        # the dag graph inside a scroller on the left
        self.graph = DagGraph(self, self.repo)
        fr = Frame(self, style="pad_medium", content=self.graph)
        scr = Scroller(self, content=fr,
                       size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        scr.bounce_set(0, 1)
        panes.part_content_set("left", scr)

        # the diff viewer on the right
        self.diff_view = DiffViewer(self, self.repo)
        self.diff_view.size_hint_weight = EXPAND_BOTH
        self.diff_view.size_hint_align = 0.0, 0.0
        panes.part_content_set("right", self.diff_view)

        self.resize(800, 600)
        self.show()
Exemple #13
0
class EgituWin(StandardWindow):
    def __init__(self):
        self.repo = None
        self.branch_selector = None
        self.caption_label = None
        self.status_label = None
        self.graph = None
        self.diff_view = None

        StandardWindow.__init__(self, "egitu", "Efl GIT gUi - Egitu")
        self.autodel_set(True)
        self.callback_delete_request_add(lambda o: elm.exit())

        # main vertical box
        box = Box(self, size_hint_weight = EXPAND_BOTH)
        self.resize_object_add(box)
        box.show()

        # header
        fr = Frame(self, style="outdent_bottom", size_hint_weight=EXPAND_HORIZ,
                   size_hint_align=FILL_BOTH)
        box.pack_end(fr)
        fr.show()

        tb = Table(self, size_hint_weight=EXPAND_HORIZ,
                  size_hint_align=FILL_BOTH)
        fr.content = tb
        tb.show()

        # main menu button
        bt = Button(self, text='Menu')
        bt.content = Icon(self, standard='home')
        bt.callback_clicked_add(lambda b: EgituMenu(self, b))
        tb.pack(bt, 0, 0, 1, 1)
        bt.show()

        # editable description entry
        self.caption_label = EditableDescription(self)
        tb.pack(self.caption_label, 1, 0, 1, 1)
        self.caption_label.show()

        # branch selector
        lb = Label(self, text='On branch')
        tb.pack(lb, 2, 0, 1, 1)
        lb.show()

        self.branch_selector = Hoversel(self, text='none')
        self.branch_selector.callback_selected_add(self.branch_selected_cb)
        tb.pack(self.branch_selector, 3, 0, 1, 1)
        self.branch_selector.show()

        # status label + button
        self.status_label = lb = Entry(self, single_line=True, editable=False)
        tb.pack(lb, 4, 0, 1, 1)
        lb.show()

        ### Main content (left + right panes)
        panes = Panes(self, content_left_size = 0.5,
                       size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        box.pack_end(panes)
        panes.show()

        # the dag graph inside a scroller on the left
        self.graph = DagGraph(self, self.repo)
        fr = Frame(self, style="pad_medium", content=self.graph)
        scr = Scroller(self, content=fr,
                       size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        scr.bounce_set(0, 1)
        panes.part_content_set("left", scr)

        # the diff viewer on the right
        self.diff_view = DiffViewer(self, self.repo)
        self.diff_view.size_hint_weight = EXPAND_BOTH
        self.diff_view.size_hint_align = 0.0, 0.0
        panes.part_content_set("right", self.diff_view)

        self.resize(800, 600)
        self.show()

    def repo_set(self, repo):
        self.repo = repo
        self.update_header()
        self.graph.populate(repo)

    def update_header(self):
        # update the branch selector
        try:
            self.branch_selector.clear()
            for branch in self.repo.branches:
                if branch == self.repo.current_branch:
                    self.branch_selector.item_add(branch, 'arrow_right', ELM_ICON_STANDARD)
                else:
                    self.branch_selector.item_add(branch)
            self.branch_selector.text = self.repo.current_branch
            self.branch_selector.content = Icon(self, standard='arrow_right')
        except:
            self.branch_selector.text = "Unknown"

        # update window title
        self.title = "%s [%s]" % (self.repo.name, self.repo.current_branch)

        # update repo description
        self.caption_label.text = self.repo.description or \
                                  'Unnamed repository; click to edit.'

        # update the status
        if self.repo.status.ahead == 1 and self.repo.status.is_clean:
            text = "<warning>Ahead by 1 commit</warning>"
        elif self.repo.status.ahead > 1 and self.repo.status.is_clean:
            text = "<warning>Ahead by {} commits</warning>".format(self.repo.status.ahead)
        elif self.repo.status.is_clean:
            text = "<success>Status is clean!</success>"
            # self.commit_button.hide()
        else:
            text = "<warning>Status is dirty !!!</warning>"
            # self.commit_button.show()

        self.status_label.text = text
        self.status_label.tooltip_text_set(self.repo.status.textual)

    def branch_selected_cb(self, flipselector, item):
        # TODO alert if unstaged changes are present
        def _switch_done_cb(success):
            self.update_header()
            self.graph.populate(self.repo)

        self.repo.current_branch_set(item.text, _switch_done_cb)

    def show_commit(self, commit):
        self.diff_view.commit_set(self.repo, commit)
def hoversel_clicked(obj):
    win = StandardWindow("hoversel", "Hoversel", autodel=True, size=(320, 320))
    if obj is None:
        win.callback_delete_request_add(lambda o: elementary.exit())

    bx = Box(win, size_hint_weight=EXPAND_BOTH)
    win.resize_object_add(bx)
    bx.show()

    bt = Hoversel(win, hover_parent=win, text="Labels",
        size_hint_weight=WEIGHT_ZERO, size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1")
    bt.item_add("Item 2")
    bt.item_add("Item 3")
    bt.item_add("Item 4 - Long Label Here")
    bx.pack_end(bt)
    bt.show()

    bt = Hoversel(win, hover_parent=win, text="Some Icons",
        size_hint_weight=WEIGHT_ZERO, size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1")
    bt.item_add("Item 2")
    bt.item_add("Item 3", "home", ELM_ICON_STANDARD)
    bt.item_add("Item 4", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    bt = Hoversel(win, hover_parent=win, text="All Icons",
        size_hint_weight=WEIGHT_ZERO, size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1", "apps", ELM_ICON_STANDARD)
    bt.item_add("Item 2", "arrow_down", ELM_ICON_STANDARD)
    bt.item_add("Item 3", "home", ELM_ICON_STANDARD)
    bt.item_add("Item 4", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    bt = Hoversel(win, hover_parent=win, text="All Icons",
        size_hint_weight=WEIGHT_ZERO, size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1", "apps", ELM_ICON_STANDARD)
    bt.item_add("Item 2", os.path.join(img_path, "logo_small.png"),
        ELM_ICON_FILE)
    bt.item_add("Item 3", "home", ELM_ICON_STANDARD)
    bt.item_add("Item 4", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    bt = Hoversel(win, hover_parent=win, text="Disabled Hoversel",
        disabled=True, size_hint_weight=WEIGHT_ZERO,
        size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1", "apps", ELM_ICON_STANDARD)
    bt.item_add("Item 2", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()


    ic = Icon(win, file=os.path.join(img_path, "sky_03.jpg"))
    bt = Hoversel(win, hover_parent=win, text="Icon + Label", content=ic,
        size_hint_weight=WEIGHT_ZERO, size_hint_align=ALIGN_CENTER)
    ic.show()

    bt.item_add("Item 1", "apps", ELM_ICON_STANDARD)
    bt.item_add("Item 2", "arrow_down", ELM_ICON_STANDARD)
    bt.item_add("Item 3", "home", ELM_ICON_STANDARD)
    bt.item_add("Item 4", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    win.show()
class FileSelector(Box):
    def __init__(self,
                 parent_widget,
                 defaultPath="",
                 defaultPopulate=True,
                 *args,
                 **kwargs):
        Box.__init__(self, parent_widget, *args, **kwargs)

        self.cancelCallback = None
        self.actionCallback = None
        self.directoryChangeCallback = None

        self.threadedFunction = ThreadedFunction()
        self._timer = ecore.Timer(0.02, self.populateFile)

        #Watch key presses for ctrl+l to select entry
        parent_widget.elm_event_callback_add(self.eventsCb)

        self.selectedFolder = None
        self.showHidden = False
        self.currentDirectory = None
        self.focusedEntry = None
        self.folderOnly = False
        self.sortReverse = False
        self.addingHidden = False
        self.pendingFiles = deque()
        self.currentSubFolders = []
        self.currentFiles = []

        #Mode should be "save" or "load"
        self.mode = "save"

        self.home = os.path.expanduser("~")
        self.root = "/"

        #Label+Entry for File Name
        self.filenameBox = Box(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.filenameBox.horizontal = True
        self.filenameBox.show()

        fileLabel = Label(self,
                          size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                          size_hint_align=FILL_HORIZ)
        fileLabel.text = "Filename:"
        fileLabel.show()

        self.fileEntry = Entry(self,
                               size_hint_weight=EXPAND_BOTH,
                               size_hint_align=FILL_HORIZ)
        self.fileEntry.single_line_set(True)
        self.fileEntry.scrollable_set(True)
        self.fileEntry.callback_changed_user_add(self.fileEntryChanged)
        self.fileEntry.show()

        self.filenameBox.pack_end(fileLabel)
        self.filenameBox.pack_end(self.fileEntry)

        sep = Separator(self,
                        size_hint_weight=EXPAND_HORIZ,
                        size_hint_align=FILL_HORIZ)
        sep.horizontal_set(True)
        sep.show()

        #Label+Entry for File Path
        self.filepathBox = Box(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.filepathBox.horizontal = True
        self.filepathBox.show()

        fileLabel = Label(self,
                          size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                          size_hint_align=FILL_HORIZ)
        fileLabel.text = "Current Folder:"
        fileLabel.show()

        self.filepathEntry = Entry(self,
                                   size_hint_weight=EXPAND_BOTH,
                                   size_hint_align=FILL_HORIZ)
        self.filepathEntry.single_line_set(True)
        self.filepathEntry.scrollable_set(True)
        self.filepathEntry.callback_changed_user_add(self.fileEntryChanged)
        self.filepathEntry.callback_unfocused_add(self.filepathEditDone)
        self.filepathEntry.callback_activated_add(self.filepathEditDone)
        #Wish this worked. Doesn't seem to do anything
        #self.filepathEntry.input_hint_set(ELM_INPUT_HINT_AUTO_COMPLETE)

        if defaultPath and os.path.isdir(defaultPath):
            startPath = defaultPath
        else:
            startPath = self.home
        self.filepathEntry.show()

        self.filepathBox.pack_end(fileLabel)
        self.filepathBox.pack_end(self.filepathEntry)

        self.autocompleteHover = Hoversel(self, hover_parent=self)
        self.autocompleteHover.callback_selected_add(self.autocompleteSelected)
        #self.autocompleteHover.show()

        self.fileSelectorBox = Panes(self,
                                     content_left_size=0.3,
                                     size_hint_weight=EXPAND_BOTH,
                                     size_hint_align=FILL_BOTH)
        self.fileSelectorBox.show()
        """Bookmarks Box contains:

            - Button - Up Arrow
            - List - Home/Root/GTK bookmarks
            - Box
            -- Button - Add Bookmark
            -- Button - Remove Bookmark"""
        self.bookmarkBox = Box(self,
                               size_hint_weight=(0.3, EVAS_HINT_EXPAND),
                               size_hint_align=FILL_BOTH)
        self.bookmarkBox.show()

        upIcon = Icon(self,
                      size_hint_weight=EXPAND_BOTH,
                      size_hint_align=FILL_BOTH)
        upIcon.standard_set("go-up")
        upIcon.show()

        self.upButton = Button(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ,
                               content=upIcon)
        self.upButton.text = "Up"
        self.upButton.callback_pressed_add(self.upButtonPressed)
        self.upButton.show()

        self.bookmarksList = List(self,
                                  size_hint_weight=EXPAND_BOTH,
                                  size_hint_align=FILL_BOTH)
        self.bookmarksList.callback_activated_add(self.bookmarkDoubleClicked)
        self.bookmarksList.show()

        self.bookmarkModBox = Box(self,
                                  size_hint_weight=EXPAND_HORIZ,
                                  size_hint_align=FILL_HORIZ)
        self.bookmarkModBox.horizontal = True
        self.bookmarkModBox.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("add")
        con.show()

        self.addButton = Button(self,
                                size_hint_weight=EXPAND_HORIZ,
                                size_hint_align=FILL_HORIZ,
                                content=con)
        self.addButton.callback_pressed_add(self.addButtonPressed)
        self.addButton.disabled = True
        self.addButton.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("remove")
        con.show()

        self.removeButton = Button(self,
                                   size_hint_weight=EXPAND_HORIZ,
                                   size_hint_align=FILL_HORIZ,
                                   content=con)
        self.removeButton.callback_pressed_add(self.removeButtonPressed)
        self.removeButton.disabled = True
        self.removeButton.show()

        self.bookmarkModBox.pack_end(self.addButton)
        self.bookmarkModBox.pack_end(self.removeButton)

        self.bookmarkBox.pack_end(self.upButton)
        self.bookmarkBox.pack_end(self.bookmarksList)
        self.bookmarkBox.pack_end(self.bookmarkModBox)

        #Directory List
        self.fileListBox = Box(self,
                               size_hint_weight=EXPAND_BOTH,
                               size_hint_align=FILL_BOTH)
        self.fileListBox.show()

        self.fileSortButton = Button(self,
                                     size_hint_weight=EXPAND_HORIZ,
                                     size_hint_align=FILL_HORIZ)
        self.fileSortButton.text = u"⬆ Name"
        self.fileSortButton.callback_pressed_add(self.sortData)
        self.fileSortButton.show()

        self.fileList = Genlist(self,
                                size_hint_weight=EXPAND_BOTH,
                                size_hint_align=FILL_BOTH,
                                homogeneous=True,
                                mode=ELM_LIST_COMPRESS)
        self.fileList.callback_activated_add(self.fileDoubleClicked)
        self.fileList.show()

        self.previewImage = previewImage = Image(self)
        #previewImage.size_hint_weight = EXPAND_BOTH
        previewImage.size_hint_align = FILL_BOTH
        previewImage.show()

        self.fileListBox.pack_end(self.fileSortButton)
        self.fileListBox.pack_end(self.fileList)
        self.fileListBox.pack_end(self.previewImage)

        self.fileSelectorBox.part_content_set("left", self.bookmarkBox)
        self.fileSelectorBox.part_content_set("right", self.fileListBox)

        #Cancel and Save/Open button
        self.buttonBox = Box(self,
                             size_hint_weight=EXPAND_HORIZ,
                             size_hint_align=(1.0, 0.5))
        self.buttonBox.horizontal = True
        self.buttonBox.show()

        self.actionIcon = Icon(self,
                               size_hint_weight=EXPAND_BOTH,
                               size_hint_align=FILL_BOTH)
        self.actionIcon.standard_set("document-save")
        self.actionIcon.show()

        self.actionButton = Button(self,
                                   size_hint_weight=(0.0, 0.0),
                                   size_hint_align=(1.0, 0.5),
                                   content=self.actionIcon)
        self.actionButton.text = "Save  "
        self.actionButton.callback_pressed_add(self.actionButtonPressed)
        self.actionButton.show()

        cancelIcon = Icon(self,
                          size_hint_weight=EXPAND_BOTH,
                          size_hint_align=FILL_BOTH)
        cancelIcon.standard_set("dialog-cancel")
        cancelIcon.show()

        self.cancelButton = Button(self,
                                   size_hint_weight=(0.0, 0.0),
                                   size_hint_align=(1.0, 0.5),
                                   content=cancelIcon)
        self.cancelButton.text = "Cancel  "
        self.cancelButton.callback_pressed_add(self.cancelButtonPressed)
        self.cancelButton.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("gtk-find")
        con.show()

        self.toggleHiddenButton = Button(self,
                                         size_hint_weight=(0.0, 0.0),
                                         size_hint_align=(1.0, 0.5),
                                         content=con)
        self.toggleHiddenButton.text = "Toggle Hidden  "
        self.toggleHiddenButton.callback_pressed_add(
            self.toggleHiddenButtonPressed)
        self.toggleHiddenButton.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("folder-new")
        con.show()

        self.createFolderButton = Button(self,
                                         size_hint_weight=(0.0, 0.0),
                                         size_hint_align=(1.0, 0.5),
                                         content=con)
        self.createFolderButton.text = "Create Folder  "
        self.createFolderButton.callback_pressed_add(
            self.createFolderButtonPressed)
        self.createFolderButton.show()

        self.buttonBox.pack_end(self.createFolderButton)
        self.buttonBox.pack_end(self.toggleHiddenButton)
        self.buttonBox.pack_end(self.cancelButton)
        self.buttonBox.pack_end(self.actionButton)

        self.pack_end(self.filenameBox)
        self.pack_end(sep)
        self.pack_end(self.filepathBox)
        self.pack_end(self.autocompleteHover)
        self.pack_end(self.fileSelectorBox)
        self.pack_end(self.buttonBox)

        self.populateBookmarks()

        self.createPopup = Popup(self)
        self.createPopup.part_text_set("title,text", "Create Folder:")

        self.createEn = en = Entry(self,
                                   size_hint_weight=EXPAND_HORIZ,
                                   size_hint_align=FILL_HORIZ)
        en.single_line_set(True)
        en.scrollable_set(True)
        en.show()

        self.createPopup.content = en

        bt = Button(self, text="Create")
        bt.callback_clicked_add(self.createFolder)
        self.createPopup.part_content_set("button1", bt)

        bt2 = Button(self, text="Cancel")
        bt2.callback_clicked_add(self.closePopup)
        self.createPopup.part_content_set("button2", bt2)

        if defaultPopulate:
            self.populateFiles(startPath)

    def folderOnlySet(self, ourValue):
        self.folderOnly = ourValue

        if not self.folderOnly:
            self.filenameBox.show()
        else:
            self.filenameBox.hide()

    def createFolder(self, obj):
        newDir = "%s%s" % (self.currentDirectory, self.createEn.text)
        os.makedirs(newDir)
        self.closePopup()
        self.populateFiles(self.currentDirectory)

    def createFolderButtonPressed(self, obj):
        self.createEn.text = ""
        self.createPopup.show()
        self.createEn.select_all()

    def closePopup(self, btn=None):
        self.createPopup.hide()

    def shutdown(self, obj=None):
        self._timer.delete()
        self.threadedFunction.shutdown()

    def sortData(self, btn):
        self.sortReverse = not self.sortReverse

        if self.sortReverse:
            self.fileSortButton.text = u"⬇ Name"
        else:
            self.fileSortButton.text = u"⬆ Name"

        self.populateFiles(self.currentDirectory)

    def populateBookmarks(self):
        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("folder_home")
        con.show()

        it = self.bookmarksList.item_append("Home", icon=con)
        it.data["path"] = self.home

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("drive-harddisk")
        con.show()

        it = self.bookmarksList.item_append("Root", icon=con)
        it.data["path"] = self.root

        it = self.bookmarksList.item_append("")
        it.separator_set(True)

        for bk in self.getGTKBookmarks():
            con = Icon(self,
                       size_hint_weight=EXPAND_BOTH,
                       size_hint_align=FILL_BOTH)
            con.standard_set("gtk-directory")
            con.show()
            it = self.bookmarksList.item_append(bk.split("/")[-1], icon=con)
            it.data["path"] = bk[7:]

    def populateFile(self):
        pen_file = len(self.pendingFiles)
        if pen_file:
            for _ in range(int(math.sqrt(pen_file))):
                ourPath, d, isDir = self.pendingFiles.popleft()
                self.packFileFolder(ourPath, d, isDir)

        #else:
        #    self._timer.freeze()

        return True

    def populateFiles(self, ourPath):
        self.autocompleteHover.hover_end()

        self.pendingFiles.clear()

        if ourPath[:-1] != "/":
            ourPath = ourPath + "/"

        if ourPath != self.filepathEntry.text or not self.showHidden:
            self.addingHidden = False

            if self.directoryChangeCallback:
                self.directoryChangeCallback(ourPath)

            del self.currentSubFolders[:]
            del self.currentFiles[:]
            self.fileList.clear()
        else:
            self.addingHidden = True

        self.filepathEntry.text = ourPath.replace("//", "/")
        self.currentDirectory = ourPath.replace("//", "/")

        self.threadedFunction.run(self.getFolderContents)
        #self._timer.thaw()

    def getFolderContents(self):
        ourPath = self.currentDirectory

        try:
            data = os.listdir(unicode(ourPath))
        except:
            data = os.listdir(str(ourPath))

        sortedData = []

        for d in data:
            isDir = os.path.isdir("%s%s" % (ourPath, d))

            if isDir:
                self.currentSubFolders.append(d)
                if self.sortReverse:
                    sortedData.append([1, d])
                else:
                    sortedData.append([0, d])
            else:
                self.currentFiles.append(d)
                if self.sortReverse:
                    sortedData.append([0, d])
                else:
                    sortedData.append([1, d])

        sortedData.sort(reverse=self.sortReverse)

        for ourFile in sortedData:
            d = ourFile[1]
            isDir = ourFile[0] if self.sortReverse else not ourFile[0]
            if self.addingHidden and d[0] == ".":
                self.pendingFiles.append([ourPath, d, isDir])
            elif (d[0] != "." or self.showHidden) and not self.addingHidden:
                self.pendingFiles.append([ourPath, d, isDir])

    def packFileFolder(self, ourPath, d, isDir):
        if isDir:
            li = GenlistItem(item_data={
                "type": "dir",
                "path": ourPath,
                "d": d
            },
                             item_class=dirglic,
                             func=self.listItemSelected)
        else:
            li = GenlistItem(item_data={
                "type": "file",
                "path": ourPath,
                "d": d
            },
                             item_class=fileglic,
                             func=self.listItemSelected)

        li.append_to(self.fileList)
        #self.fileList.go()
        #print("Adding: %s %s %s"%(ourPath, d, isDir))

    def fileDoubleClicked(self, obj, item=None, eventData=None):
        if item.data["type"] == "dir":
            self.addButton.disabled = True
            self.removeButton.disabled = True
            self.populateFiles(item.data["path"] + item.text)
        else:
            self.actionButtonPressed(self.actionButton)

    def getGTKBookmarks(self):
        try:
            with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'),
                      'r') as f:
                ourBks = []
                for x in f:
                    x = x.split(" ")[0]
                    x = x.replace("%20", " ")
                    x = x.strip()
                    ourBks.append(x)
                return ourBks
        except IOError:
            return []

    def bookmarkDoubleClicked(self, obj, item=None, eventData=None):
        item.selected_set(False)
        self.addButton.disabled = True
        self.removeButton.disabled = True
        self.populateFiles(item.data["path"])

    def listItemSelected(self, item, gl, data):
        if item.data["type"] == "dir":
            self.directorySelected(item)
        else:
            self.fileSelected(item.text)
            item.selected_set(False)

    def fileSelected(self, ourFile):
        self.fileEntry.text = ourFile
        self.addButton.disabled = True
        self.removeButton.disabled = True
        self.selectedFolder = None

        #Update image preview if an image is selected
        if ourFile[-3:] in ["jpg", "png", "gif"]:
            self.previewImage.file_set("%s/%s" %
                                       (self.filepathEntry.text, ourFile))
            self.previewImage.size_hint_weight = (1.0, 0.4)
        else:
            self.previewImage.size_hint_weight = (0, 0)

    def directorySelected(self, btn):
        ourPath = btn.data["path"]
        if btn == self.selectedFolder:
            self.populateFiles(ourPath)
            self.addButton.disabled = True
        else:
            self.selectedFolder = btn

            currentMarks = self.getGTKBookmarks()

            toAppend = "file://%s%s" % (self.filepathEntry.text,
                                        self.selectedFolder.text)

            if toAppend not in currentMarks:
                self.addButton.disabled = False
                self.removeButton.disabled = True
            else:
                self.addButton.disabled = True
                self.removeButton.disabled = False

    def upButtonPressed(self, btn):
        ourSplit = self.filepathEntry.text.split("/")
        del ourSplit[-1]
        del ourSplit[-1]
        self.populateFiles("/".join(ourSplit))

    def addButtonPressed(self, btn):
        toAppend = "file://%s%s" % (self.filepathEntry.text,
                                    self.selectedFolder.text.replace(
                                        " ", "%20"))

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("gtk-directory")
        con.show()
        it = self.bookmarksList.item_append(self.selectedFolder.text, icon=con)
        it.data["path"] = "%s%s" % (self.filepathEntry.text,
                                    self.selectedFolder.text)

        self.bookmarksList.go()

        self.addButton.disabled = True
        self.removeButton.disabled = False

        with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'), 'a') as f:
            f.write(toAppend + " " + self.selectedFolder.text + "\n")

    def removeButtonPressed(self, btn):
        toRemove = "file://%s%s" % (self.filepathEntry.text,
                                    self.selectedFolder.text)

        bks = self.getGTKBookmarks()
        bks.remove(toRemove)

        with open(os.path.expanduser('~/.config/gtk-3.0/bookmarks'), 'w') as f:
            for b in bks:
                bName = b.split("/")[-1]
                b = b.replace(" ", "%20")
                f.write(b + " " + bName + "\n")

        self.bookmarksList.clear()
        self.populateBookmarks()

        self.addButton.disabled = False
        self.removeButton.disabled = True

    def setMode(self, ourMode):
        self.mode = ourMode.lower()

        self.actionButton.text = "%s  " % ourMode
        self.actionIcon.standard_set("document-%s" % ourMode.lower())

        if self.mode != "save":
            self.createFolderButton.hide()
        else:
            self.createFolderButton.show()

    def eventsCb(self, obj, src, event_type, event):
        if event.modifier_is_set(
                "Control") and event_type == EVAS_CALLBACK_KEY_DOWN:
            if event.key.lower() == "l":
                self.filepathEntry.focus_set(True)
                self.filepathEntry.cursor_end_set()

    def toggleHiddenButtonPressed(self, btn):
        self.showHidden = not self.showHidden
        self.populateFiles(self.filepathEntry.text)

    def toggleHidden(self):
        self.showHidden = not self.showHidden
        self.populateFiles(self.filepathEntry.text)

    def callback_cancel_add(self, cb):
        self.cancelCallback = cb

    def callback_activated_add(self, cb):
        self.actionCallback = cb

    def callback_directory_open_add(self, cb):
        self.directoryChangeCallback = cb

    def cancelButtonPressed(self, btn):
        if self.cancelCallback:
            self.cancelCallback(self)

    def actionButtonPressed(self, btn):
        if self.actionCallback:
            if not self.folderOnly and self.fileEntry.text:
                self.actionCallback(
                    self,
                    "%s%s" % (self.filepathEntry.text, self.fileEntry.text))
            elif self.folderOnly:
                self.actionCallback(self, "%s" % (self.filepathEntry.text))

    def fileEntryChanged(self, en):
        typed = en.text.split("/")[-1]

        newList = []

        self.focusedEntry = en

        if en == self.filepathEntry:
            for x in self.currentSubFolders:
                if typed in x:
                    if len(newList) < 10:
                        newList.append(x)
                    else:
                        break
        else:
            for x in self.currentFiles:
                if typed in x:
                    if len(newList) < 10:
                        newList.append(x)
                    else:
                        break

        if self.autocompleteHover.expanded_get():
            self.autocompleteHover.hover_end()

        self.autocompleteHover.clear()

        for x in newList:
            self.autocompleteHover.item_add(x)

        self.autocompleteHover.hover_begin()

    def autocompleteSelected(self, hov, item):
        hov.hover_end()
        if self.focusedEntry == self.filepathEntry:
            self.populateFiles("%s%s" % (self.currentDirectory, item.text))
            self.filepathEntry.cursor_end_set()
        else:
            self.fileEntry.text = item.text
            self.fileEntry.cursor_end_set()

    def filepathEditDone(self, en):
        if os.path.isdir(en.text) and en.text != self.currentDirectory:
            self.populateFiles(en.text)
            self.filepathEntry.cursor_end_set()
        else:
            #en.text = self.currentDirectory
            pass

    def selected_get(self):
        return "%s%s" % (self.filepathEntry.text, self.fileEntry.text)
Exemple #16
0
class EgituWin(StandardWindow):
    def __init__(self, app):
        self.app = app
        self.branch_selector = None
        self.caption_label = None
        self.status_label = None
        self.graph = None
        self.diff_view = None

        StandardWindow.__init__(self, 'egitu', 'Efl GIT gUi - Egitu',
                                size=(1000,600), autodel=True)
        self.callback_delete_request_add(lambda o: elm.exit())

    def populate(self):
        # main vertical box
        box = Box(self, size_hint_weight = EXPAND_BOTH)
        self.resize_object_add(box)
        box.show()

        ### header
        fr = Frame(self, style='outdent_bottom', size_hint_weight=EXPAND_HORIZ,
                   size_hint_align=FILL_BOTH)
        box.pack_end(fr)
        fr.show()

        tb = Table(self, padding=(3,3),
                   size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH)
        fr.content = tb
        tb.show()

        # main menu button
        bt = MainMenuButton(self.app)
        tb.pack(bt, 0, 0, 1, 1)
        bt.show()

        # editable description entry
        self.caption_label = EditableDescription(self.app)
        tb.pack(self.caption_label, 1, 0, 1, 1)
        self.caption_label.show()

        # status label + button
        lb = Entry(self, editable=False, line_wrap=ELM_WRAP_NONE)
        lb.text_style_user_push("DEFAULT='align=center'")
        tb.pack(lb, 2, 0, 1, 1)
        lb.show()
        self.status_label = lb

        # branch selector
        self.branch_selector = Hoversel(self, text='HEAD', disabled=True,
                                        content=SafeIcon(self, 'git-branch'))
        self.branch_selector.callback_selected_add(self.branch_selected_cb)
        tb.pack(self.branch_selector, 3, 0, 1, 1)
        self.branch_selector.show()

        # pull button
        bt = Button(self, text='Pull', disabled=True,
                    content=SafeIcon(self, 'git-pull'))
        bt.callback_clicked_add(self.app.action_pull)
        tb.pack(bt, 4, 0, 1, 1)
        bt.show()
        self.pull_btn = bt

        # push button
        bt = Button(self, text='Push', disabled=True,
                    content=SafeIcon(self, 'git-push'))
        bt.callback_clicked_add(self.app.action_push)
        tb.pack(bt, 5, 0, 1, 1)
        bt.show()
        self.push_btn = bt

        ### Tree panes
        panes1 = Panes(self, content_left_min_size=200, content_left_size=0.0,
                      size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        box.pack_end(panes1)
        panes1.show()

        # the sidebar on the left
        self.sidebar = Sidebar(self, self.app)
        panes1.part_content_set('left', self.sidebar)

        ### Main content (left + right panes)
        panes2 = Panes(self, content_left_size=0.5,
                       size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        panes1.part_content_set('right', panes2)
        panes2.show()

        # the dag graph in the center
        self.graph = DagGraph(self, self.app)
        panes2.part_content_set('left', self.graph)

        # the diff viewer on the right
        self.diff_view = DiffViewer(self, self.app)
        self.diff_view.size_hint_weight = EXPAND_BOTH
        self.diff_view.size_hint_align = 0.0, 0.0
        panes2.part_content_set('right', self.diff_view)

        #
        self.show()

    def update_header(self):
        repo = self.app.repo

        # update window title
        self.title = '%s (%s)' % (repo.name, repo.status.head_describe)

        # update repo description
        if self.app.repo is None:
            self.caption_label.text = 'No repository loaded'
        elif repo.description:
            self.caption_label.text = repo.description
        else:
            self.caption_label.text = 'Unnamed repository; click to edit.'

        # update the branch selector
        if self.app.repo is None:
            self.branch_selector.clear()
            self.branch_selector.text = 'No repository'
            self.branch_selector.disabled = True
        else:
            self.branch_selector.clear()
            self.branch_selector.disabled = False
            for branch in repo.branches:
                ic = 'arrow-right' if branch.is_current else 'git-branch'
                self.branch_selector.item_add(branch.name, ic, ELM_ICON_STANDARD)
            if repo.status.head_detached:
                if repo.status.head_to_tag:
                    ic = SafeIcon(self.branch_selector, 'git-tag')
                else:
                    ic = SafeIcon(self.branch_selector, 'git-commit')
            else:
                ic = SafeIcon(self.branch_selector, 'git-branch')
            self.branch_selector.content = ic
            self.branch_selector.text = repo.status.head_describe

        # update the status label
        status = repo.status
        if status.is_merging:
            text = "<warning>!! MERGING !!</warning>"
        elif status.is_cherry:
            text = "<warning>!! CHERRY-PICKING !!</warning>"
        elif status.is_reverting:
            text = "<warning>!! REVERTING !!</warning>"
        elif status.is_bisecting:
            text = "<warning>!! BISECTING !!</warning>"
        elif status.is_clean:
            text = '<success>Status is clean!</success>'
        else:
            text = '<warning>Status is dirty!</warning>'

        if status.ahead > 0:
            text += '<br><info>Ahead by {} {}</info>'.format(
                status.ahead, 'commit' if status.ahead == 1 else 'commits')
        if status.behind > 0:
            text += '<br><info>Behind by {} {}</info>'.format(
                status.behind, 'commit' if status.behind == 1 else 'commits')
        
        self.status_label.text = text
        self.status_label.tooltip_text_set(status.textual)
        
        # push/pull buttons
        self.pull_btn.disabled = self.push_btn.disabled = self.app.repo is None

    def branch_selected_cb(self, hoversel, item):
        self.app.checkout_ref(item.text)

    def _binds_cb_refresh(self, src, key, event):
        self.refresh()
        return True

    def _binds_cb_open(self, src, key, event):
        RepoSelector(self.app)
        return True

    def _binds_cb_quit(self, src, key, event):
        elm.exit()
        return True

    def _binds_cb_branches(self, src, key, event):
        BranchesDialog(self.app, self)
        return True

    def _binds_cb_push(self, src, key, event):
        PushPopup(self, self.app)
        return True

    def _binds_cb_pull(self, src, key, event):
        PullPopup(self, self.app)
        return True
    def __init__(self,
                 parent_widget,
                 defaultPath="",
                 defaultPopulate=True,
                 *args,
                 **kwargs):
        Box.__init__(self, parent_widget, *args, **kwargs)

        self.cancelCallback = None
        self.actionCallback = None
        self.directoryChangeCallback = None

        self.threadedFunction = ThreadedFunction()
        self._timer = ecore.Timer(0.02, self.populateFile)

        #Watch key presses for ctrl+l to select entry
        parent_widget.elm_event_callback_add(self.eventsCb)

        self.selectedFolder = None
        self.showHidden = False
        self.currentDirectory = None
        self.focusedEntry = None
        self.folderOnly = False
        self.sortReverse = False
        self.addingHidden = False
        self.pendingFiles = deque()
        self.currentSubFolders = []
        self.currentFiles = []

        #Mode should be "save" or "load"
        self.mode = "save"

        self.home = os.path.expanduser("~")
        self.root = "/"

        #Label+Entry for File Name
        self.filenameBox = Box(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.filenameBox.horizontal = True
        self.filenameBox.show()

        fileLabel = Label(self,
                          size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                          size_hint_align=FILL_HORIZ)
        fileLabel.text = "Filename:"
        fileLabel.show()

        self.fileEntry = Entry(self,
                               size_hint_weight=EXPAND_BOTH,
                               size_hint_align=FILL_HORIZ)
        self.fileEntry.single_line_set(True)
        self.fileEntry.scrollable_set(True)
        self.fileEntry.callback_changed_user_add(self.fileEntryChanged)
        self.fileEntry.show()

        self.filenameBox.pack_end(fileLabel)
        self.filenameBox.pack_end(self.fileEntry)

        sep = Separator(self,
                        size_hint_weight=EXPAND_HORIZ,
                        size_hint_align=FILL_HORIZ)
        sep.horizontal_set(True)
        sep.show()

        #Label+Entry for File Path
        self.filepathBox = Box(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ)
        self.filepathBox.horizontal = True
        self.filepathBox.show()

        fileLabel = Label(self,
                          size_hint_weight=(0.15, EVAS_HINT_EXPAND),
                          size_hint_align=FILL_HORIZ)
        fileLabel.text = "Current Folder:"
        fileLabel.show()

        self.filepathEntry = Entry(self,
                                   size_hint_weight=EXPAND_BOTH,
                                   size_hint_align=FILL_HORIZ)
        self.filepathEntry.single_line_set(True)
        self.filepathEntry.scrollable_set(True)
        self.filepathEntry.callback_changed_user_add(self.fileEntryChanged)
        self.filepathEntry.callback_unfocused_add(self.filepathEditDone)
        self.filepathEntry.callback_activated_add(self.filepathEditDone)
        #Wish this worked. Doesn't seem to do anything
        #self.filepathEntry.input_hint_set(ELM_INPUT_HINT_AUTO_COMPLETE)

        if defaultPath and os.path.isdir(defaultPath):
            startPath = defaultPath
        else:
            startPath = self.home
        self.filepathEntry.show()

        self.filepathBox.pack_end(fileLabel)
        self.filepathBox.pack_end(self.filepathEntry)

        self.autocompleteHover = Hoversel(self, hover_parent=self)
        self.autocompleteHover.callback_selected_add(self.autocompleteSelected)
        #self.autocompleteHover.show()

        self.fileSelectorBox = Panes(self,
                                     content_left_size=0.3,
                                     size_hint_weight=EXPAND_BOTH,
                                     size_hint_align=FILL_BOTH)
        self.fileSelectorBox.show()
        """Bookmarks Box contains:

            - Button - Up Arrow
            - List - Home/Root/GTK bookmarks
            - Box
            -- Button - Add Bookmark
            -- Button - Remove Bookmark"""
        self.bookmarkBox = Box(self,
                               size_hint_weight=(0.3, EVAS_HINT_EXPAND),
                               size_hint_align=FILL_BOTH)
        self.bookmarkBox.show()

        upIcon = Icon(self,
                      size_hint_weight=EXPAND_BOTH,
                      size_hint_align=FILL_BOTH)
        upIcon.standard_set("go-up")
        upIcon.show()

        self.upButton = Button(self,
                               size_hint_weight=EXPAND_HORIZ,
                               size_hint_align=FILL_HORIZ,
                               content=upIcon)
        self.upButton.text = "Up"
        self.upButton.callback_pressed_add(self.upButtonPressed)
        self.upButton.show()

        self.bookmarksList = List(self,
                                  size_hint_weight=EXPAND_BOTH,
                                  size_hint_align=FILL_BOTH)
        self.bookmarksList.callback_activated_add(self.bookmarkDoubleClicked)
        self.bookmarksList.show()

        self.bookmarkModBox = Box(self,
                                  size_hint_weight=EXPAND_HORIZ,
                                  size_hint_align=FILL_HORIZ)
        self.bookmarkModBox.horizontal = True
        self.bookmarkModBox.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("add")
        con.show()

        self.addButton = Button(self,
                                size_hint_weight=EXPAND_HORIZ,
                                size_hint_align=FILL_HORIZ,
                                content=con)
        self.addButton.callback_pressed_add(self.addButtonPressed)
        self.addButton.disabled = True
        self.addButton.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("remove")
        con.show()

        self.removeButton = Button(self,
                                   size_hint_weight=EXPAND_HORIZ,
                                   size_hint_align=FILL_HORIZ,
                                   content=con)
        self.removeButton.callback_pressed_add(self.removeButtonPressed)
        self.removeButton.disabled = True
        self.removeButton.show()

        self.bookmarkModBox.pack_end(self.addButton)
        self.bookmarkModBox.pack_end(self.removeButton)

        self.bookmarkBox.pack_end(self.upButton)
        self.bookmarkBox.pack_end(self.bookmarksList)
        self.bookmarkBox.pack_end(self.bookmarkModBox)

        #Directory List
        self.fileListBox = Box(self,
                               size_hint_weight=EXPAND_BOTH,
                               size_hint_align=FILL_BOTH)
        self.fileListBox.show()

        self.fileSortButton = Button(self,
                                     size_hint_weight=EXPAND_HORIZ,
                                     size_hint_align=FILL_HORIZ)
        self.fileSortButton.text = u"⬆ Name"
        self.fileSortButton.callback_pressed_add(self.sortData)
        self.fileSortButton.show()

        self.fileList = Genlist(self,
                                size_hint_weight=EXPAND_BOTH,
                                size_hint_align=FILL_BOTH,
                                homogeneous=True,
                                mode=ELM_LIST_COMPRESS)
        self.fileList.callback_activated_add(self.fileDoubleClicked)
        self.fileList.show()

        self.previewImage = previewImage = Image(self)
        #previewImage.size_hint_weight = EXPAND_BOTH
        previewImage.size_hint_align = FILL_BOTH
        previewImage.show()

        self.fileListBox.pack_end(self.fileSortButton)
        self.fileListBox.pack_end(self.fileList)
        self.fileListBox.pack_end(self.previewImage)

        self.fileSelectorBox.part_content_set("left", self.bookmarkBox)
        self.fileSelectorBox.part_content_set("right", self.fileListBox)

        #Cancel and Save/Open button
        self.buttonBox = Box(self,
                             size_hint_weight=EXPAND_HORIZ,
                             size_hint_align=(1.0, 0.5))
        self.buttonBox.horizontal = True
        self.buttonBox.show()

        self.actionIcon = Icon(self,
                               size_hint_weight=EXPAND_BOTH,
                               size_hint_align=FILL_BOTH)
        self.actionIcon.standard_set("document-save")
        self.actionIcon.show()

        self.actionButton = Button(self,
                                   size_hint_weight=(0.0, 0.0),
                                   size_hint_align=(1.0, 0.5),
                                   content=self.actionIcon)
        self.actionButton.text = "Save  "
        self.actionButton.callback_pressed_add(self.actionButtonPressed)
        self.actionButton.show()

        cancelIcon = Icon(self,
                          size_hint_weight=EXPAND_BOTH,
                          size_hint_align=FILL_BOTH)
        cancelIcon.standard_set("dialog-cancel")
        cancelIcon.show()

        self.cancelButton = Button(self,
                                   size_hint_weight=(0.0, 0.0),
                                   size_hint_align=(1.0, 0.5),
                                   content=cancelIcon)
        self.cancelButton.text = "Cancel  "
        self.cancelButton.callback_pressed_add(self.cancelButtonPressed)
        self.cancelButton.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("gtk-find")
        con.show()

        self.toggleHiddenButton = Button(self,
                                         size_hint_weight=(0.0, 0.0),
                                         size_hint_align=(1.0, 0.5),
                                         content=con)
        self.toggleHiddenButton.text = "Toggle Hidden  "
        self.toggleHiddenButton.callback_pressed_add(
            self.toggleHiddenButtonPressed)
        self.toggleHiddenButton.show()

        con = Icon(self,
                   size_hint_weight=EXPAND_BOTH,
                   size_hint_align=FILL_BOTH)
        con.standard_set("folder-new")
        con.show()

        self.createFolderButton = Button(self,
                                         size_hint_weight=(0.0, 0.0),
                                         size_hint_align=(1.0, 0.5),
                                         content=con)
        self.createFolderButton.text = "Create Folder  "
        self.createFolderButton.callback_pressed_add(
            self.createFolderButtonPressed)
        self.createFolderButton.show()

        self.buttonBox.pack_end(self.createFolderButton)
        self.buttonBox.pack_end(self.toggleHiddenButton)
        self.buttonBox.pack_end(self.cancelButton)
        self.buttonBox.pack_end(self.actionButton)

        self.pack_end(self.filenameBox)
        self.pack_end(sep)
        self.pack_end(self.filepathBox)
        self.pack_end(self.autocompleteHover)
        self.pack_end(self.fileSelectorBox)
        self.pack_end(self.buttonBox)

        self.populateBookmarks()

        self.createPopup = Popup(self)
        self.createPopup.part_text_set("title,text", "Create Folder:")

        self.createEn = en = Entry(self,
                                   size_hint_weight=EXPAND_HORIZ,
                                   size_hint_align=FILL_HORIZ)
        en.single_line_set(True)
        en.scrollable_set(True)
        en.show()

        self.createPopup.content = en

        bt = Button(self, text="Create")
        bt.callback_clicked_add(self.createFolder)
        self.createPopup.part_content_set("button1", bt)

        bt2 = Button(self, text="Cancel")
        bt2.callback_clicked_add(self.closePopup)
        self.createPopup.part_content_set("button2", bt2)

        if defaultPopulate:
            self.populateFiles(startPath)
def map_clicked(obj):
    win = StandardWindow("map", "Map test", autodel=True, size=(600, 600))
    if obj is None:
        win.callback_delete_request_add(lambda o: elementary.exit())

    vbox = Box(win)
    vbox.size_hint_weight = EXPAND_BOTH
    vbox.size_hint_align = FILL_BOTH
    win.resize_object_add(vbox)
    vbox.show()

    map_obj = Map(win, zoom=2)
    map_obj.size_hint_weight = EXPAND_BOTH
    map_obj.size_hint_align = FILL_BOTH
    map_obj.callback_tile_load_add(cb_map_load)
    map_obj.callback_tile_loaded_add(cb_map_load)
    map_obj.event_callback_add(EVAS_CALLBACK_MOUSE_DOWN, cb_map_mouse_down)
    vbox.pack_end(map_obj)
    map_obj.show()

    ###
    lb = Label(win, text="load_status: 0 / 0")
    vbox.pack_end(lb)
    lb.show()
    map_obj.data["lb_load_status"] = lb

    ###
    hbox = Box(win, horizontal=True)
    hbox.size_hint_weight = EXPAND_HORIZ
    hbox.size_hint_align = FILL_HORIZ
    vbox.pack_end(hbox)
    hbox.show()

    bt = Button(win, text="Goto")
    bt.callback_clicked_add(cb_btn_goto, map_obj)
    hbox.pack_end(bt)
    bt.show()

    bt = Button(win, text="Zoom +")
    bt.callback_clicked_add(cb_btn_zoom, map_obj, 1)
    hbox.pack_end(bt)
    bt.show()

    bt = Button(win, text="Zoom -")
    bt.callback_clicked_add(cb_btn_zoom, map_obj, -1)
    hbox.pack_end(bt)
    bt.show()

    sl = Slider(win, text="Rotation:", min_max=(0, 360), value=0,
        indicator_format="%3.0f")
    sl.callback_changed_add(cb_slider_rot, map_obj)
    hbox.pack_end(sl)
    sl.show()

    src_type = ELM_MAP_SOURCE_TYPE_TILE
    ho = Hoversel(win, hover_parent=win,
                  text="Tiles: %s" % (map_obj.source_get(src_type)))
    for src in map_obj.sources_get(src_type):
        ho.item_add(src)
    ho.callback_selected_add(cb_hovsel_selected, map_obj, src_type, "Tiles")
    hbox.pack_end(ho)
    ho.show()

    ###
    hbox = Box(win, horizontal=True)
    hbox.size_hint_weight = EXPAND_HORIZ
    hbox.size_hint_align = FILL_HORIZ
    vbox.pack_end(hbox)
    hbox.show()

    ck = Check(win, text="wheel_disabled")
    ck.callback_changed_add(lambda bt: map_obj.wheel_disabled_set(bt.state))
    hbox.pack_end(ck)
    ck.show()

    ck = Check(win, text="paused")
    ck.callback_changed_add(lambda bt: map_obj.paused_set(bt.state))
    hbox.pack_end(ck)
    ck.show()

    ck = Check(win, text="hide overlays")
    ck.callback_changed_add(cb_chk_overlays_hidden, map_obj)
    hbox.pack_end(ck)
    ck.show()

    ck = Check(win, text="pause overlays")
    ck.callback_changed_add(cb_chk_overlays_paused, map_obj)
    hbox.pack_end(ck)
    ck.show()

    ###
    sp = Separator(win, horizontal=True)
    sp.show()
    vbox.pack_end(sp)

    hbox = Box(win, horizontal=True)
    hbox.size_hint_weight = EXPAND_HORIZ
    hbox.size_hint_align = FILL_HORIZ
    vbox.pack_end(hbox)
    hbox.show()

    src_type = ELM_MAP_SOURCE_TYPE_ROUTE
    ho = Hoversel(win, hover_parent=win,
                  text="Routes: %s" % (map_obj.source_get(src_type)))
    for src in map_obj.sources_get(src_type):
        ho.item_add(src)
    ho.callback_selected_add(cb_hovsel_selected, map_obj, src_type, "Routes")
    hbox.pack_end(ho)
    ho.show()

    lb = Label(win, text="Set Start and End point to calculate route")
    hbox.pack_end(lb)
    lb.show()
    map_obj.data["lb_distance"] = lb

    bt = Button(win, text="Calc route")
    bt.callback_clicked_add(cb_btn_calc_route, map_obj)
    hbox.pack_end(bt)
    bt.show()

    ###
    sp = Separator(win, horizontal=True)
    sp.show()
    vbox.pack_end(sp)

    hbox = Box(win, horizontal=True)
    hbox.size_hint_weight = EXPAND_HORIZ
    hbox.size_hint_align = FILL_HORIZ
    vbox.pack_end(hbox)
    hbox.show()
    
    src_type = ELM_MAP_SOURCE_TYPE_NAME
    ho = Hoversel(win, hover_parent=win,
                  text="Names: %s" % (map_obj.source_get(src_type)))
    for src in map_obj.sources_get(src_type):
        ho.item_add(src)
    ho.callback_selected_add(cb_hovsel_selected, map_obj, src_type, "Names")
    hbox.pack_end(ho)
    ho.show()

    en = Entry(win, scrollable=True, text="type an address here")
    en.size_hint_weight = EXPAND_BOTH
    en.size_hint_align = FILL_BOTH
    en.single_line = True
    hbox.pack_end(en)
    en.show()

    bt = Button(win, text="Search address")
    bt.callback_clicked_add(cb_btn_search_name, map_obj, en)
    hbox.pack_end(bt)
    bt.show()

    bt = Button(win, text="Search start point")
    bt.callback_clicked_add(cb_btn_search_region, map_obj, en)
    hbox.pack_end(bt)
    bt.show()


    print_map_info(map_obj)
    win.show()
Exemple #19
0
def hoversel_clicked(obj):
    win = StandardWindow("hoversel", "Hoversel", autodel=True, size=(320, 320))
    if obj is None:
        win.callback_delete_request_add(lambda o: elementary.exit())

    bx = Box(win, size_hint_weight=EXPAND_BOTH)
    win.resize_object_add(bx)
    bx.show()

    bt = Hoversel(win,
                  hover_parent=win,
                  text="Labels",
                  size_hint_weight=WEIGHT_ZERO,
                  size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1")
    bt.item_add("Item 2")
    bt.item_add("Item 3")
    bt.item_add("Item 4 - Long Label Here")
    bx.pack_end(bt)
    bt.show()

    bt = Hoversel(win,
                  hover_parent=win,
                  text="Some Icons",
                  size_hint_weight=WEIGHT_ZERO,
                  size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1")
    bt.item_add("Item 2")
    bt.item_add("Item 3", "home", ELM_ICON_STANDARD)
    bt.item_add("Item 4", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    bt = Hoversel(win,
                  hover_parent=win,
                  text="All Icons",
                  size_hint_weight=WEIGHT_ZERO,
                  size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1", "apps", ELM_ICON_STANDARD)
    bt.item_add("Item 2", "arrow_down", ELM_ICON_STANDARD)
    bt.item_add("Item 3", "home", ELM_ICON_STANDARD)
    bt.item_add("Item 4", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    bt = Hoversel(win,
                  hover_parent=win,
                  text="All Icons",
                  size_hint_weight=WEIGHT_ZERO,
                  size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1", "apps", ELM_ICON_STANDARD)
    bt.item_add("Item 2", os.path.join(img_path, "logo_small.png"),
                ELM_ICON_FILE)
    bt.item_add("Item 3", "home", ELM_ICON_STANDARD)
    bt.item_add("Item 4", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    bt = Hoversel(win,
                  hover_parent=win,
                  text="Disabled Hoversel",
                  disabled=True,
                  size_hint_weight=WEIGHT_ZERO,
                  size_hint_align=ALIGN_CENTER)
    bt.item_add("Item 1", "apps", ELM_ICON_STANDARD)
    bt.item_add("Item 2", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    ic = Icon(win, file=os.path.join(img_path, "sky_03.jpg"))
    bt = Hoversel(win,
                  hover_parent=win,
                  text="Icon + Label",
                  content=ic,
                  size_hint_weight=WEIGHT_ZERO,
                  size_hint_align=ALIGN_CENTER)
    ic.show()

    bt.item_add("Item 1", "apps", ELM_ICON_STANDARD)
    bt.item_add("Item 2", "arrow_down", ELM_ICON_STANDARD)
    bt.item_add("Item 3", "home", ELM_ICON_STANDARD)
    bt.item_add("Item 4", "close", ELM_ICON_STANDARD)
    bx.pack_end(bt)
    bt.show()

    win.show()