diff --git a/bin/pytop-0-0-1-x64.deb b/bin/pytop-0-0-1-x64.deb index 487c746..e752683 100644 Binary files a/bin/pytop-0-0-1-x64.deb and b/bin/pytop-0-0-1-x64.deb differ diff --git a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Events.py b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Events.py index 59eb536..4615ba6 100644 --- a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Events.py +++ b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Events.py @@ -1,19 +1,10 @@ # Gtk Imports -import gi, threading -gi.require_version('Gtk', '3.0') -gi.require_version('Gdk', '3.0') - -from gi.repository import Gtk as gtk -from gi.repository import Gdk as gdk - # Python imports from .Grid import Grid from .Dragging import Dragging -from threading import Thread - class Events: def __init__(self, settings): self.settings = settings @@ -32,14 +23,12 @@ class Events: selectedDirDialog.set_filename(self.desktopPath) self.grid = None - self.setDir(selectedDirDialog) + self.setIconViewDir(selectedDirDialog) - def setDir(self, widget, data=None): + def setIconViewDir(self, widget, data=None): newPath = widget.get_filename() - self.grid = Grid(self.desktop, self.settings) - Thread(target=self.grid.generateDirectoryGrid, args=(newPath,)).start() - # Grid(self.desktop, self.settings).generateDirectoryGrid(newPath) + Grid(self.desktop, self.settings, newPath) def showGridControlMenu(self, widget, data=None): popover = self.builder.get_object("gridControlMenu") @@ -70,6 +59,8 @@ class Events: def pasteFile(self): pass + def test(self, widget, data=None): + print(widget) # Webview events def showWebview(self, widget): diff --git a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/FileHandler.py b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/FileHandler.py index 047a509..c4dfa3b 100644 --- a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/FileHandler.py +++ b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/FileHandler.py @@ -1,5 +1,11 @@ -import os, shutil, subprocess +import os, shutil, subprocess, threading + + +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs).start() + return wrapper class FileHandler: def __init__(self): @@ -22,7 +28,7 @@ class FileHandler: self.MPLAYER_WH = " -xy 1600 -geometry 50%:50% "; self.MPV_WH = " -geometry 50%:50% "; - + @threaded def openFile(self, file): print("Opening: " + file) if file.lower().endswith(self.vids): diff --git a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Grid.py b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Grid.py index 76a424d..e750f85 100644 --- a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Grid.py +++ b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Grid.py @@ -7,44 +7,55 @@ gi.require_version('Gdk', '3.0') from gi.repository import Gtk as gtk from gi.repository import Gdk as gdk +from gi.repository import GdkPixbuf from gi.repository import GObject as gobject # Python imports -import os, subprocess, threading, hashlib +import os, threading from os.path import isdir, isfile, join from os import listdir -from threading import Thread from .Icon import Icon from .FileHandler import FileHandler gdk.threads_init() + +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs).start() + return wrapper + class Grid: - def __init__(self, desktop, settings): - self.desktop = desktop - self.settings = settings - self.filehandler = FileHandler() - - self.usrHome = settings.returnUserHome() - self.builder = self.settings.returnBuilder() - self.ColumnSize = self.settings.returnColumnSize() - self.thubnailGen = self.settings.getThumbnailGenerator() + def __init__(self, desktop, settings, newPath): + self.desktop = desktop + self.settings = settings + self.filehandler = FileHandler() + self.store = gtk.ListStore(GdkPixbuf.Pixbuf, str) + self.usrHome = settings.returnUserHome() + self.builder = self.settings.returnBuilder() + self.ColumnSize = self.settings.returnColumnSize() self.currentPath = "" self.selectedFile = "" + self.desktop.set_model(self.store) + self.desktop.set_pixbuf_column(0) + self.desktop.set_text_column(1) + self.desktop.connect("item-activated", self.iconLeftClickEventManager) + self.desktop.connect("button_press_event", self.iconRightClickEventManager, (self.desktop,)) - def generateDirectoryGrid(self, dirPath): - loadProgress = self.builder.get_object('loadProgress') - loadProgress.set_text("Loading...") - loadProgress.set_fraction(0.0) - self.clearGrid(self.desktop) - self.currentPath = dirPath + self.setIconViewDir(newPath) + + @threaded + def setIconViewDir(self, path): + self.store.clear() + + self.currentPath = path dirPaths = ['.', '..'] files = [] - for f in listdir(dirPath): - file = join(dirPath, f) + for f in listdir(path): + file = join(path, f) if self.settings.isHideHiddenFiles(): if f.startswith('.'): continue @@ -53,7 +64,12 @@ class Grid: else: dirPaths.append(f) - vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm') + dirPaths.sort() + files.sort() + files = dirPaths + files + self.generateDirectoryGrid(path, files) + + def generateDirectoryGrid(self, dirPath, files): fractionTick = 1.0 / 1.0 if len(files) == 0 else len(files) tickCount = 0.0 row = 0 @@ -61,100 +77,65 @@ class Grid: x = 0 y = 0 - dirPaths.sort() - files.sort() - files = dirPaths + files + loadProgress = self.builder.get_object('loadProgress') + loadProgress.set_text("Loading...") + loadProgress.set_fraction(0.0) + for file in files: - eveBox = gtk.EventBox() - - # Generate any thumbnails beforehand... - if file.lower().endswith(vidsList): - fullPathFile = dirPath + "/" + file - fileHash = hashlib.sha256(str.encode(fullPathFile)).hexdigest() - hashImgpth = self.usrHome + "/.thumbnails/normal/" + fileHash + ".png" - if isfile(hashImgpth) == False: - self.generateVideoThumbnail(fullPathFile, hashImgpth) - eveBox = self.generateIcon(dirPath, file, col, row) - else: - eveBox = self.generateIcon(dirPath, file, col, row) - - eveBox.show_all() - gobject.idle_add(self.addToGrid, (self.desktop, eveBox, col, row,)) - tickCount = tickCount + fractionTick + imgBuffer = Icon(self.settings).createIcon(dirPath, file) + gobject.idle_add(self.addToGrid, (imgBuffer, file,)) + tickCount += fractionTick loadProgress.set_fraction(tickCount) - col += 1 - if col == self.ColumnSize: - col = 0 - row += 1 - loadProgress.set_text("Finished...") - def generateIcon(self, dirPath, file, col, row): - eveBox = Icon(self.settings).createIcon(dirPath, file) - # self.drag.connectEvents(self.desktop, eveBox) - eveBox.connect("button_press_event", self.iconClickEventManager, (eveBox,)) - eveBox.connect("enter_notify_event", self.settings.mouseOver, ()) - eveBox.connect("leave_notify_event", self.settings.mouseOut, ()) - return eveBox - - def addToGrid(self, args): - args[0].attach(args[1], args[2], args[3], 1, 1) + self.store.append([args[0], args[1]]) - def clearGrid(self, object): - while True: - if object.get_child_at(0,0)!= None: - object.remove_row(0) - else: - break - - def iconClickEventManager(self, widget, eve, params): + def iconLeftClickEventManager(self, widget, item): try: - self.settings.setSelected(params[0]) - children = widget.get_children()[0].get_children() - fileName = children[1].get_text() + model = widget.get_model() + fileName = model[item][1] dir = self.currentPath file = dir + "/" + fileName - if eve.type == gdk.EventType.DOUBLE_BUTTON_PRESS: - if fileName == ".": - self.setNewPath(dir) - elif fileName == "..": - parentDir = os.path.abspath(os.path.join(dir, os.pardir)) - self.currentPath = parentDir - self.setNewPath(parentDir) - elif isdir(file): - self.currentPath = file - self.setNewPath(self.currentPath) - elif isfile(file): - self.filehandler.openFile(file) - elif eve.type == gdk.EventType.BUTTON_PRESS and eve.button == 3: - input = self.builder.get_object("iconRenameInput") - popover = self.builder.get_object("iconControlsWindow") - self.selectedFile = file # Used for return to caller + if fileName == ".": + self.setIconViewDir(dir) + elif fileName == "..": + parentDir = os.path.abspath(os.path.join(dir, os.pardir)) + self.currentPath = parentDir + self.setIconViewDir(parentDir) + elif isdir(file): + self.currentPath = file + self.setIconViewDir(self.currentPath) + elif isfile(file): + self.filehandler.openFile(file) + except Exception as e: + print(e) - input.set_text(fileName) - popover.set_relative_to(children[1]) + def iconRightClickEventManager(self, widget, eve, params): + try: + if eve.type == gdk.EventType.BUTTON_PRESS and eve.button == 3: + # # NOTE: Need to change name of listview box... + # children = widget.get_children()[0].get_children() + # fileName = children[1].get_text() + # dir = self.currentPath + # file = dir + "/" + fileName + # + # input = self.builder.get_object("iconRenameInput") + popover = self.builder.get_object("iconControlsWindow") + # self.selectedFile = file # Used for return to caller + # + # input.set_text(fileName) + popover.set_relative_to(widget) popover.set_position(gtk.PositionType.RIGHT) popover.show_all() popover.popup() except Exception as e: print(e) - def generateVideoThumbnail(self, fullPathFile, hashImgpth): - subprocess.call([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPathFile, "-o", hashImgpth]) - def setNewPath(self, path): - self.generateDirectoryGrid(path) - # NOTE: Threading here causes seg faults. My theory is that - # the calling threading dies b/c the grid itself is cleard - # of children and the child is the one that has the 'thread' - # - # Thread(target=self.generateDirectoryGrid, args=(path,)).start() - - - # Pass through file control events + # Passthrough file control events def createFile(arg): pass diff --git a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Icon.py b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Icon.py index bd40516..a0c22c1 100644 --- a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Icon.py +++ b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Icon.py @@ -8,40 +8,30 @@ from gi.repository import Gtk as gtk from gi.repository import Gio as gio from gi.repository import GdkPixbuf -import os, hashlib +import os, subprocess, hashlib, threading from os.path import isdir, isfile, join +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs).start() + return wrapper + class Icon: def __init__(self, settings): - self.usrHome = settings.returnUserHome() + self.settings = settings + self.thubnailGen = self.settings.getThumbnailGenerator() + self.GTK_ORIENTATION = settings.returnIconImagePos() + self.usrHome = settings.returnUserHome() self.iconContainerWxH = settings.returnContainerWH() self.systemIconImageWxH = settings.returnSystemIconImageWH() self.viIconWxH = settings.returnVIIconWH() def createIcon(self, dir, file): fullPathFile = dir + "/" + file - eveBox = gtk.EventBox() - icon = gtk.Box() - label = gtk.Label() thumbnl = self.getIconImage(file, fullPathFile) - - label.set_max_width_chars(1) - label.set_ellipsize(3) # ELLIPSIZE_END (3) - label.set_lines(2) - label.set_line_wrap(True) - label.set_line_wrap_mode(2) # WRAP_WORD (0) WRAP_CHAR (1) WRAP_WORD_CHAR (2) - label.set_text(file) - - icon.set_size_request(self.iconContainerWxH[0], self.iconContainerWxH[1]); - icon.set_property('orientation', self.GTK_ORIENTATION) - icon.add(thumbnl) - icon.add(label) - - eveBox.add(icon) - eveBox.show_all() - return eveBox + return thumbnl def getIconImage(self, file, fullPathFile): thumbnl = gtk.Image() @@ -51,16 +41,31 @@ class Icon: if file.lower().endswith(vidsList): fileHash = hashlib.sha256(str.encode(fullPathFile)).hexdigest() hashImgpth = self.usrHome + "/.thumbnails/normal/" + fileHash + ".png" - thumbnl = self.createIconImageFromBuffer(hashImgpth, self.viIconWxH) + + # Generate any thumbnails beforehand... + try: + if isfile(hashImgpth) == False: + self.generateVideoThumbnail(fullPathFile, hashImgpth) + thumbnl = self.createIconImageBuffer(hashImgpth, self.viIconWxH) + else: + thumbnl = self.createIconImageBuffer(hashImgpth, self.viIconWxH) + except Exception as e: + print(e) + thumbPth = self.getSystemThumbnail(fullPathFile, self.systemIconImageWxH[0]) + thumbnl = self.createIconImageBuffer(thumbPth, self.systemIconImageWxH) + elif file.lower().endswith(imagesList): - thumbnl = self.createIconImageFromBuffer(fullPathFile, self.viIconWxH) + thumbnl = self.createIconImageBuffer(fullPathFile, self.viIconWxH) else: thumbPth = self.getSystemThumbnail(fullPathFile, self.systemIconImageWxH[0]) - thumbnl = self.createIconImageFromBuffer(thumbPth, self.systemIconImageWxH) + thumbnl = self.createIconImageBuffer(thumbPth, self.systemIconImageWxH) - return thumbnl + # NOTE: Returning pixbuf through retreval to keep this file more universaly usable. + # We can just remove get_pixbuf to get a gtk image + return thumbnl.get_pixbuf() - def createIconImageFromBuffer(self, path, wxh): + def createIconImageBuffer(self, path, wxh): + pixbuf = None try: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( filename = path, @@ -86,3 +91,7 @@ class Icon: final_filename = icon_file.get_filename() return final_filename + + def generateVideoThumbnail(self, fullPathFile, hashImgpth): + proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPathFile, "-o", hashImgpth]) + proc.wait() diff --git a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Settings.py b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Settings.py index 7a64ed4..4f3638f 100644 --- a/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Settings.py +++ b/src/debs/pytop-0-0-1-x64/opt/Pytop/utils/Settings.py @@ -9,17 +9,15 @@ from gi.repository import Gdk as gdk class Settings: def __init__(self): - self.builder = None - self.hoveredFile = None - self.selectedFile = None - - self.DEFAULTCOLOR = gdk.RGBA(0.0, 0.0, 0.0, 0.0) # ~#00000000 - self.MOUSEOVERCOLOR = gdk.RGBA(0.0, 0.9, 1.0, 0.64) # ~#00e8ff - self.SELECTEDCOLOR = gdk.RGBA(0.4, 0.5, 0.1, 0.84) - self.GTK_ORIENTATION = 1 # HORIZONTAL (0) VERTICAL (1) - self.THUMB_GENERATOR = "ffmpegthumbnailer" - + self.builder = None self.hideHiddenFiles = True + + self.GTK_ORIENTATION = 1 # HORIZONTAL (0) VERTICAL (1) + self.THUMB_GENERATOR = "ffmpegthumbnailer" + self.DEFAULTCOLOR = gdk.RGBA(0.0, 0.0, 0.0, 0.0) # ~#00000000 + self.MOUSEOVERCOLOR = gdk.RGBA(0.0, 0.9, 1.0, 0.64) # ~#00e8ff + self.SELECTEDCOLOR = gdk.RGBA(0.4, 0.5, 0.1, 0.84) + self.webHome = 'http://webfm.com/' self.usrHome = os.path.expanduser('~') self.desktopPath = self.usrHome + "/Desktop" @@ -80,27 +78,6 @@ class Settings: def returnWebHome(self): return self.webHome def isHideHiddenFiles(self): return self.hideHiddenFiles - def mouseOver(self, widget, eve, args): - hand_cursor = gdk.Cursor(gdk.CursorType.HAND2) - self.builder.get_object("Window").get_window().set_cursor(hand_cursor) - if widget != self.selectedFile: - widget.override_background_color(gtk.StateType.NORMAL, self.MOUSEOVERCOLOR) - - def mouseOut(self, widget, eve, args): - watch_cursor = gdk.Cursor(gdk.CursorType.LEFT_PTR) - self.builder.get_object("Window").get_window().set_cursor(watch_cursor) - if widget != self.selectedFile: - widget.override_background_color(gtk.StateType.NORMAL, self.DEFAULTCOLOR) - - def setSelected(self, eveBox): - if self.selectedFile: - self.selectedFile.override_background_color(gtk.StateType.NORMAL, self.DEFAULTCOLOR) - - eveBox.override_background_color(gtk.StateType.NORMAL, self.SELECTEDCOLOR) - self.selectedFile = eveBox - - - def setDefaultWebviewSettings(self, widget, settings=None): # Usability settings.set_property('enable-fullscreen', True) diff --git a/src/versions/pytop-0.0.1/Pytop/utils/Events.py b/src/versions/pytop-0.0.1/Pytop/utils/Events.py index 59eb536..4615ba6 100644 --- a/src/versions/pytop-0.0.1/Pytop/utils/Events.py +++ b/src/versions/pytop-0.0.1/Pytop/utils/Events.py @@ -1,19 +1,10 @@ # Gtk Imports -import gi, threading -gi.require_version('Gtk', '3.0') -gi.require_version('Gdk', '3.0') - -from gi.repository import Gtk as gtk -from gi.repository import Gdk as gdk - # Python imports from .Grid import Grid from .Dragging import Dragging -from threading import Thread - class Events: def __init__(self, settings): self.settings = settings @@ -32,14 +23,12 @@ class Events: selectedDirDialog.set_filename(self.desktopPath) self.grid = None - self.setDir(selectedDirDialog) + self.setIconViewDir(selectedDirDialog) - def setDir(self, widget, data=None): + def setIconViewDir(self, widget, data=None): newPath = widget.get_filename() - self.grid = Grid(self.desktop, self.settings) - Thread(target=self.grid.generateDirectoryGrid, args=(newPath,)).start() - # Grid(self.desktop, self.settings).generateDirectoryGrid(newPath) + Grid(self.desktop, self.settings, newPath) def showGridControlMenu(self, widget, data=None): popover = self.builder.get_object("gridControlMenu") @@ -70,6 +59,8 @@ class Events: def pasteFile(self): pass + def test(self, widget, data=None): + print(widget) # Webview events def showWebview(self, widget): diff --git a/src/versions/pytop-0.0.1/Pytop/utils/FileHandler.py b/src/versions/pytop-0.0.1/Pytop/utils/FileHandler.py index 047a509..c4dfa3b 100644 --- a/src/versions/pytop-0.0.1/Pytop/utils/FileHandler.py +++ b/src/versions/pytop-0.0.1/Pytop/utils/FileHandler.py @@ -1,5 +1,11 @@ -import os, shutil, subprocess +import os, shutil, subprocess, threading + + +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs).start() + return wrapper class FileHandler: def __init__(self): @@ -22,7 +28,7 @@ class FileHandler: self.MPLAYER_WH = " -xy 1600 -geometry 50%:50% "; self.MPV_WH = " -geometry 50%:50% "; - + @threaded def openFile(self, file): print("Opening: " + file) if file.lower().endswith(self.vids): diff --git a/src/versions/pytop-0.0.1/Pytop/utils/Grid.py b/src/versions/pytop-0.0.1/Pytop/utils/Grid.py index 76a424d..e750f85 100644 --- a/src/versions/pytop-0.0.1/Pytop/utils/Grid.py +++ b/src/versions/pytop-0.0.1/Pytop/utils/Grid.py @@ -7,44 +7,55 @@ gi.require_version('Gdk', '3.0') from gi.repository import Gtk as gtk from gi.repository import Gdk as gdk +from gi.repository import GdkPixbuf from gi.repository import GObject as gobject # Python imports -import os, subprocess, threading, hashlib +import os, threading from os.path import isdir, isfile, join from os import listdir -from threading import Thread from .Icon import Icon from .FileHandler import FileHandler gdk.threads_init() + +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs).start() + return wrapper + class Grid: - def __init__(self, desktop, settings): - self.desktop = desktop - self.settings = settings - self.filehandler = FileHandler() - - self.usrHome = settings.returnUserHome() - self.builder = self.settings.returnBuilder() - self.ColumnSize = self.settings.returnColumnSize() - self.thubnailGen = self.settings.getThumbnailGenerator() + def __init__(self, desktop, settings, newPath): + self.desktop = desktop + self.settings = settings + self.filehandler = FileHandler() + self.store = gtk.ListStore(GdkPixbuf.Pixbuf, str) + self.usrHome = settings.returnUserHome() + self.builder = self.settings.returnBuilder() + self.ColumnSize = self.settings.returnColumnSize() self.currentPath = "" self.selectedFile = "" + self.desktop.set_model(self.store) + self.desktop.set_pixbuf_column(0) + self.desktop.set_text_column(1) + self.desktop.connect("item-activated", self.iconLeftClickEventManager) + self.desktop.connect("button_press_event", self.iconRightClickEventManager, (self.desktop,)) - def generateDirectoryGrid(self, dirPath): - loadProgress = self.builder.get_object('loadProgress') - loadProgress.set_text("Loading...") - loadProgress.set_fraction(0.0) - self.clearGrid(self.desktop) - self.currentPath = dirPath + self.setIconViewDir(newPath) + + @threaded + def setIconViewDir(self, path): + self.store.clear() + + self.currentPath = path dirPaths = ['.', '..'] files = [] - for f in listdir(dirPath): - file = join(dirPath, f) + for f in listdir(path): + file = join(path, f) if self.settings.isHideHiddenFiles(): if f.startswith('.'): continue @@ -53,7 +64,12 @@ class Grid: else: dirPaths.append(f) - vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm') + dirPaths.sort() + files.sort() + files = dirPaths + files + self.generateDirectoryGrid(path, files) + + def generateDirectoryGrid(self, dirPath, files): fractionTick = 1.0 / 1.0 if len(files) == 0 else len(files) tickCount = 0.0 row = 0 @@ -61,100 +77,65 @@ class Grid: x = 0 y = 0 - dirPaths.sort() - files.sort() - files = dirPaths + files + loadProgress = self.builder.get_object('loadProgress') + loadProgress.set_text("Loading...") + loadProgress.set_fraction(0.0) + for file in files: - eveBox = gtk.EventBox() - - # Generate any thumbnails beforehand... - if file.lower().endswith(vidsList): - fullPathFile = dirPath + "/" + file - fileHash = hashlib.sha256(str.encode(fullPathFile)).hexdigest() - hashImgpth = self.usrHome + "/.thumbnails/normal/" + fileHash + ".png" - if isfile(hashImgpth) == False: - self.generateVideoThumbnail(fullPathFile, hashImgpth) - eveBox = self.generateIcon(dirPath, file, col, row) - else: - eveBox = self.generateIcon(dirPath, file, col, row) - - eveBox.show_all() - gobject.idle_add(self.addToGrid, (self.desktop, eveBox, col, row,)) - tickCount = tickCount + fractionTick + imgBuffer = Icon(self.settings).createIcon(dirPath, file) + gobject.idle_add(self.addToGrid, (imgBuffer, file,)) + tickCount += fractionTick loadProgress.set_fraction(tickCount) - col += 1 - if col == self.ColumnSize: - col = 0 - row += 1 - loadProgress.set_text("Finished...") - def generateIcon(self, dirPath, file, col, row): - eveBox = Icon(self.settings).createIcon(dirPath, file) - # self.drag.connectEvents(self.desktop, eveBox) - eveBox.connect("button_press_event", self.iconClickEventManager, (eveBox,)) - eveBox.connect("enter_notify_event", self.settings.mouseOver, ()) - eveBox.connect("leave_notify_event", self.settings.mouseOut, ()) - return eveBox - - def addToGrid(self, args): - args[0].attach(args[1], args[2], args[3], 1, 1) + self.store.append([args[0], args[1]]) - def clearGrid(self, object): - while True: - if object.get_child_at(0,0)!= None: - object.remove_row(0) - else: - break - - def iconClickEventManager(self, widget, eve, params): + def iconLeftClickEventManager(self, widget, item): try: - self.settings.setSelected(params[0]) - children = widget.get_children()[0].get_children() - fileName = children[1].get_text() + model = widget.get_model() + fileName = model[item][1] dir = self.currentPath file = dir + "/" + fileName - if eve.type == gdk.EventType.DOUBLE_BUTTON_PRESS: - if fileName == ".": - self.setNewPath(dir) - elif fileName == "..": - parentDir = os.path.abspath(os.path.join(dir, os.pardir)) - self.currentPath = parentDir - self.setNewPath(parentDir) - elif isdir(file): - self.currentPath = file - self.setNewPath(self.currentPath) - elif isfile(file): - self.filehandler.openFile(file) - elif eve.type == gdk.EventType.BUTTON_PRESS and eve.button == 3: - input = self.builder.get_object("iconRenameInput") - popover = self.builder.get_object("iconControlsWindow") - self.selectedFile = file # Used for return to caller + if fileName == ".": + self.setIconViewDir(dir) + elif fileName == "..": + parentDir = os.path.abspath(os.path.join(dir, os.pardir)) + self.currentPath = parentDir + self.setIconViewDir(parentDir) + elif isdir(file): + self.currentPath = file + self.setIconViewDir(self.currentPath) + elif isfile(file): + self.filehandler.openFile(file) + except Exception as e: + print(e) - input.set_text(fileName) - popover.set_relative_to(children[1]) + def iconRightClickEventManager(self, widget, eve, params): + try: + if eve.type == gdk.EventType.BUTTON_PRESS and eve.button == 3: + # # NOTE: Need to change name of listview box... + # children = widget.get_children()[0].get_children() + # fileName = children[1].get_text() + # dir = self.currentPath + # file = dir + "/" + fileName + # + # input = self.builder.get_object("iconRenameInput") + popover = self.builder.get_object("iconControlsWindow") + # self.selectedFile = file # Used for return to caller + # + # input.set_text(fileName) + popover.set_relative_to(widget) popover.set_position(gtk.PositionType.RIGHT) popover.show_all() popover.popup() except Exception as e: print(e) - def generateVideoThumbnail(self, fullPathFile, hashImgpth): - subprocess.call([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPathFile, "-o", hashImgpth]) - def setNewPath(self, path): - self.generateDirectoryGrid(path) - # NOTE: Threading here causes seg faults. My theory is that - # the calling threading dies b/c the grid itself is cleard - # of children and the child is the one that has the 'thread' - # - # Thread(target=self.generateDirectoryGrid, args=(path,)).start() - - - # Pass through file control events + # Passthrough file control events def createFile(arg): pass diff --git a/src/versions/pytop-0.0.1/Pytop/utils/Icon.py b/src/versions/pytop-0.0.1/Pytop/utils/Icon.py index bd40516..a0c22c1 100644 --- a/src/versions/pytop-0.0.1/Pytop/utils/Icon.py +++ b/src/versions/pytop-0.0.1/Pytop/utils/Icon.py @@ -8,40 +8,30 @@ from gi.repository import Gtk as gtk from gi.repository import Gio as gio from gi.repository import GdkPixbuf -import os, hashlib +import os, subprocess, hashlib, threading from os.path import isdir, isfile, join +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs).start() + return wrapper + class Icon: def __init__(self, settings): - self.usrHome = settings.returnUserHome() + self.settings = settings + self.thubnailGen = self.settings.getThumbnailGenerator() + self.GTK_ORIENTATION = settings.returnIconImagePos() + self.usrHome = settings.returnUserHome() self.iconContainerWxH = settings.returnContainerWH() self.systemIconImageWxH = settings.returnSystemIconImageWH() self.viIconWxH = settings.returnVIIconWH() def createIcon(self, dir, file): fullPathFile = dir + "/" + file - eveBox = gtk.EventBox() - icon = gtk.Box() - label = gtk.Label() thumbnl = self.getIconImage(file, fullPathFile) - - label.set_max_width_chars(1) - label.set_ellipsize(3) # ELLIPSIZE_END (3) - label.set_lines(2) - label.set_line_wrap(True) - label.set_line_wrap_mode(2) # WRAP_WORD (0) WRAP_CHAR (1) WRAP_WORD_CHAR (2) - label.set_text(file) - - icon.set_size_request(self.iconContainerWxH[0], self.iconContainerWxH[1]); - icon.set_property('orientation', self.GTK_ORIENTATION) - icon.add(thumbnl) - icon.add(label) - - eveBox.add(icon) - eveBox.show_all() - return eveBox + return thumbnl def getIconImage(self, file, fullPathFile): thumbnl = gtk.Image() @@ -51,16 +41,31 @@ class Icon: if file.lower().endswith(vidsList): fileHash = hashlib.sha256(str.encode(fullPathFile)).hexdigest() hashImgpth = self.usrHome + "/.thumbnails/normal/" + fileHash + ".png" - thumbnl = self.createIconImageFromBuffer(hashImgpth, self.viIconWxH) + + # Generate any thumbnails beforehand... + try: + if isfile(hashImgpth) == False: + self.generateVideoThumbnail(fullPathFile, hashImgpth) + thumbnl = self.createIconImageBuffer(hashImgpth, self.viIconWxH) + else: + thumbnl = self.createIconImageBuffer(hashImgpth, self.viIconWxH) + except Exception as e: + print(e) + thumbPth = self.getSystemThumbnail(fullPathFile, self.systemIconImageWxH[0]) + thumbnl = self.createIconImageBuffer(thumbPth, self.systemIconImageWxH) + elif file.lower().endswith(imagesList): - thumbnl = self.createIconImageFromBuffer(fullPathFile, self.viIconWxH) + thumbnl = self.createIconImageBuffer(fullPathFile, self.viIconWxH) else: thumbPth = self.getSystemThumbnail(fullPathFile, self.systemIconImageWxH[0]) - thumbnl = self.createIconImageFromBuffer(thumbPth, self.systemIconImageWxH) + thumbnl = self.createIconImageBuffer(thumbPth, self.systemIconImageWxH) - return thumbnl + # NOTE: Returning pixbuf through retreval to keep this file more universaly usable. + # We can just remove get_pixbuf to get a gtk image + return thumbnl.get_pixbuf() - def createIconImageFromBuffer(self, path, wxh): + def createIconImageBuffer(self, path, wxh): + pixbuf = None try: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( filename = path, @@ -86,3 +91,7 @@ class Icon: final_filename = icon_file.get_filename() return final_filename + + def generateVideoThumbnail(self, fullPathFile, hashImgpth): + proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPathFile, "-o", hashImgpth]) + proc.wait() diff --git a/src/versions/pytop-0.0.1/Pytop/utils/Settings.py b/src/versions/pytop-0.0.1/Pytop/utils/Settings.py index 7a64ed4..4f3638f 100644 --- a/src/versions/pytop-0.0.1/Pytop/utils/Settings.py +++ b/src/versions/pytop-0.0.1/Pytop/utils/Settings.py @@ -9,17 +9,15 @@ from gi.repository import Gdk as gdk class Settings: def __init__(self): - self.builder = None - self.hoveredFile = None - self.selectedFile = None - - self.DEFAULTCOLOR = gdk.RGBA(0.0, 0.0, 0.0, 0.0) # ~#00000000 - self.MOUSEOVERCOLOR = gdk.RGBA(0.0, 0.9, 1.0, 0.64) # ~#00e8ff - self.SELECTEDCOLOR = gdk.RGBA(0.4, 0.5, 0.1, 0.84) - self.GTK_ORIENTATION = 1 # HORIZONTAL (0) VERTICAL (1) - self.THUMB_GENERATOR = "ffmpegthumbnailer" - + self.builder = None self.hideHiddenFiles = True + + self.GTK_ORIENTATION = 1 # HORIZONTAL (0) VERTICAL (1) + self.THUMB_GENERATOR = "ffmpegthumbnailer" + self.DEFAULTCOLOR = gdk.RGBA(0.0, 0.0, 0.0, 0.0) # ~#00000000 + self.MOUSEOVERCOLOR = gdk.RGBA(0.0, 0.9, 1.0, 0.64) # ~#00e8ff + self.SELECTEDCOLOR = gdk.RGBA(0.4, 0.5, 0.1, 0.84) + self.webHome = 'http://webfm.com/' self.usrHome = os.path.expanduser('~') self.desktopPath = self.usrHome + "/Desktop" @@ -80,27 +78,6 @@ class Settings: def returnWebHome(self): return self.webHome def isHideHiddenFiles(self): return self.hideHiddenFiles - def mouseOver(self, widget, eve, args): - hand_cursor = gdk.Cursor(gdk.CursorType.HAND2) - self.builder.get_object("Window").get_window().set_cursor(hand_cursor) - if widget != self.selectedFile: - widget.override_background_color(gtk.StateType.NORMAL, self.MOUSEOVERCOLOR) - - def mouseOut(self, widget, eve, args): - watch_cursor = gdk.Cursor(gdk.CursorType.LEFT_PTR) - self.builder.get_object("Window").get_window().set_cursor(watch_cursor) - if widget != self.selectedFile: - widget.override_background_color(gtk.StateType.NORMAL, self.DEFAULTCOLOR) - - def setSelected(self, eveBox): - if self.selectedFile: - self.selectedFile.override_background_color(gtk.StateType.NORMAL, self.DEFAULTCOLOR) - - eveBox.override_background_color(gtk.StateType.NORMAL, self.SELECTEDCOLOR) - self.selectedFile = eveBox - - - def setDefaultWebviewSettings(self, widget, settings=None): # Usability settings.set_property('enable-fullscreen', True)