Changed grid making process. Cleaned up Icon logic.
This commit is contained in:
parent
f147922ca8
commit
d23a8606f0
@ -2,7 +2,7 @@
|
||||
Pytop is a Gtk + Python gui to have a custom desktop interface.
|
||||
|
||||
# Notes
|
||||
```sudo apt-get install python3 steamcmd
|
||||
```sudo apt-get install python3 wget steamcmd```
|
||||
|
||||
# TODO
|
||||
<ul>
|
||||
|
@ -29,5 +29,8 @@ class Main:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main = Main()
|
||||
gtk.main()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
@ -17,7 +17,6 @@
|
||||
</object>
|
||||
<object class="GtkWindow" id="Window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="default_width">800</property>
|
||||
<property name="default_height">600</property>
|
||||
<property name="type_hint">desktop</property>
|
||||
@ -101,6 +100,8 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="selection_mode">multiple</property>
|
||||
<property name="columns">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -115,10 +116,10 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopoverMenu" id="iconControlsWindow">
|
||||
<object class="GtkPopover" id="iconControlsWindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="relative_to">Desktop</property>
|
||||
<property name="position">right</property>
|
||||
<property name="relative_to">popOutBttn</property>
|
||||
<property name="position">bottom</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
@ -212,9 +213,6 @@
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="submenu">main</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="webViewer">
|
||||
|
@ -34,3 +34,55 @@ cell:focus {
|
||||
outline-style: solid;
|
||||
outline-color: rgba(0, 232, 255, 0.64);
|
||||
}
|
||||
|
||||
|
||||
/* Ivonview and children default color */
|
||||
.view {
|
||||
background-color: rgba(0, 0, 0, 0.22);
|
||||
color: #ebebeb;
|
||||
}
|
||||
|
||||
|
||||
/* Hover over color when not selected */
|
||||
.view:hover {
|
||||
box-shadow: inset 0 0 0 9999px alpha(rgba(0, 232, 255, 0.64), 0.54);
|
||||
}
|
||||
|
||||
/* Handles the icon selection hover and selected hover color. */
|
||||
.view:selected,
|
||||
.view:selected:hover {
|
||||
box-shadow: inset 0 0 0 9999px rgba(15, 134, 13, 0.49);
|
||||
}
|
||||
|
||||
/* Rubberband coloring */
|
||||
.rubberband,
|
||||
rubberband,
|
||||
flowbox rubberband,
|
||||
treeview.view rubberband,
|
||||
.content-view rubberband,
|
||||
.content-view .rubberband,
|
||||
XfdesktopIconView.view .rubberband {
|
||||
border: 1px solid #6c6c6c;
|
||||
background-color: rgba(21, 158, 167, 0.57);
|
||||
}
|
||||
|
||||
XfdesktopIconView.view:active {
|
||||
background-color: rgba(172, 102, 21, 1);
|
||||
}
|
||||
|
||||
|
||||
XfdesktopIconView.view {
|
||||
border-radius: 4px;
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
XfdesktopIconView.view:active {
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
XfdesktopIconView.view .rubberband {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
@ -41,9 +41,16 @@ class Grid:
|
||||
self.desktop.set_text_column(1)
|
||||
self.desktop.connect("item-activated", self.iconLeftClickEventManager)
|
||||
self.desktop.connect("button_press_event", self.iconRightClickEventManager, (self.desktop,))
|
||||
self.desktop.connect("selection-changed", self.setIconSelectionArray, (self.desktop,))
|
||||
|
||||
self.vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
||||
self.imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
||||
self.copyCutArry = []
|
||||
|
||||
|
||||
self.gtkLock = False # Thread checks for gtkLock
|
||||
self.threadLock = False # Gtk checks for thread lock
|
||||
self.toWorkPool = [] # Thread fills pool and gtk empties it
|
||||
|
||||
self.setIconViewDir(newPath)
|
||||
|
||||
@ -81,18 +88,56 @@ class Grid:
|
||||
files.sort()
|
||||
|
||||
files = dirPaths + vids + images + desktop + files
|
||||
self.generateDirectoryGrid(path, files)
|
||||
self.generateDirectoryGrid(path, files) # Run helper thread...
|
||||
glib.idle_add(self.addToGrid, (file,)) # This must stay in the main thread b/c
|
||||
# gtk isn't thread safe/aware So, we
|
||||
# make a sad lil thread hot potato 'game'
|
||||
# out of this process.
|
||||
|
||||
|
||||
@threaded
|
||||
def generateDirectoryGrid(self, dirPath, files):
|
||||
# NOTE: We'll be passing pixbuf after retreval to keep Icon.py file more
|
||||
# universaly usable. We can just remove get_pixbuf to get a gtk.Image type
|
||||
storageQue = []
|
||||
for file in files:
|
||||
image = Icon(self.settings).createIcon(dirPath, file)
|
||||
# NOTE: Passing pixbuf after retreval to keep Icon.py file more universaly usable.
|
||||
# We can just remove get_pixbuf to get a gtk image
|
||||
glib.idle_add(self.addToGrid, (image.get_pixbuf(), file,))
|
||||
|
||||
if len(storageQue) > 0:
|
||||
for dataSet in storageQue:
|
||||
self.toWorkPool.append(dataSet)
|
||||
|
||||
self.toWorkPool.append([image.get_pixbuf(), file])
|
||||
self.threadLock = False
|
||||
self.gtkLock = True
|
||||
storageQue.clear()
|
||||
|
||||
|
||||
def addToGrid(self, args):
|
||||
self.store.append([args[0], args[1]])
|
||||
# NOTE: Returning true tells gtk to check again in the future when idle.
|
||||
# False ends checks and "continues normal flow"
|
||||
files = args[0]
|
||||
|
||||
if len(self.toWorkPool) > 0:
|
||||
for dataSet in self.toWorkPool:
|
||||
self.store.append(dataSet)
|
||||
|
||||
if len(self.store) == len(files): # Vonfirm processed all files and cleanup
|
||||
self.gtkLock = False
|
||||
self.threadLock = False
|
||||
self.toWorkPool.clear()
|
||||
return False
|
||||
# Check again when idle. If nothing else is updating
|
||||
# this function gets called immediatly so we play hot potato
|
||||
else:
|
||||
self.toWorkPool.clear()
|
||||
self.gtkLock = False
|
||||
self.threadLock = True
|
||||
return True
|
||||
|
||||
def setIconSelectionArray(self, widget, data=None):
|
||||
os.system('cls||clear')
|
||||
print(data)
|
||||
|
||||
def iconLeftClickEventManager(self, widget, item):
|
||||
try:
|
||||
@ -121,8 +166,6 @@ class Grid:
|
||||
popover = self.builder.get_object("iconControlsWindow")
|
||||
popover.show_all()
|
||||
popover.popup()
|
||||
print(popover)
|
||||
|
||||
# # NOTE: Need to change name of listview box...
|
||||
# children = widget.get_children()[0].get_children()
|
||||
# fileName = children[1].get_text()
|
||||
|
@ -28,66 +28,61 @@ class Icon:
|
||||
|
||||
self.GTK_ORIENTATION = settings.returnIconImagePos()
|
||||
self.usrHome = settings.returnUserHome()
|
||||
self.iconContainerWxH = settings.returnContainerWH()
|
||||
self.systemIconImageWxH = settings.returnSystemIconImageWH()
|
||||
self.viIconWxH = settings.returnVIIconWH()
|
||||
self.iconContainerWH = settings.returnContainerWH()
|
||||
self.systemIconImageWH = settings.returnSystemIconImageWH()
|
||||
self.viIconWH = settings.returnVIIconWH()
|
||||
|
||||
|
||||
def createIcon(self, dir, file):
|
||||
fullPath = dir + "/" + file
|
||||
thumbnl = self.getIconImage(file, fullPath)
|
||||
return thumbnl
|
||||
return self.getIconImage(file, fullPath)
|
||||
|
||||
|
||||
def getIconImage(self, file, fullPath):
|
||||
thumbnl = gtk.Image()
|
||||
try:
|
||||
thumbnl = None
|
||||
vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
||||
imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
||||
|
||||
try:
|
||||
if file.lower().endswith(vidsList): # Video thumbnail
|
||||
# Video thumbnail
|
||||
if file.lower().endswith(vidsList):
|
||||
fileHash = hashlib.sha256(str.encode(fullPath)).hexdigest()
|
||||
hashImgpth = self.usrHome + "/.thumbnails/normal/" + fileHash + ".png"
|
||||
hashImgPth = self.usrHome + "/.thumbnails/normal/" + fileHash + ".png"
|
||||
|
||||
if isfile(hashImgpth) == False:
|
||||
self.generateVideoThumbnail(fullPath, hashImgpth)
|
||||
if isfile(hashImgPth) == False:
|
||||
self.generateVideoThumbnail(fullPath, hashImgPth)
|
||||
|
||||
thumbnl = self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
||||
elif file.lower().endswith(imagesList): # Image Icon
|
||||
thumbnl = self.createIconImageBuffer(fullPath, self.viIconWxH)
|
||||
else: # System icons
|
||||
thumbnl = self.nonImageOrVideoIcon(fullPath)
|
||||
thumbnl = self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||
# Image Icon
|
||||
elif file.lower().endswith(imagesList):
|
||||
thumbnl = self.createIconImageBuffer(fullPath, self.viIconWH)
|
||||
# .desktop file parsing
|
||||
elif fullPath.lower().endswith( ('.desktop',) ):
|
||||
thumbnl = self.parseDesktopFiles(fullPath)
|
||||
# System icons
|
||||
else:
|
||||
thumbnl = self.getSystemThumbnail(fullPath, self.systemIconImageWH[0])
|
||||
|
||||
if thumbnl == None: # If no icon, try stock file icon...
|
||||
thumbnl = gtk.Image.new_from_icon_name("gtk-file", gtk.IconSize.LARGE_TOOLBAR)
|
||||
|
||||
if thumbnl == None: # If no icon whatsoever, return internal default
|
||||
thumbnl = gtk.Image.new_from_file("resources/icons/bin.png")
|
||||
|
||||
return thumbnl
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return gtk.Image.new_from_file("resources/icons/bin.png")
|
||||
|
||||
if thumbnl == None: # If no system icon, try stock file icon...
|
||||
thumbnl = gtk.Image.new_from_icon_name("gtk-file", gtk.IconSize.LARGE_TOOLBAR)
|
||||
if thumbnl == None:
|
||||
thumbnl = gtk.Image.new_from_file("resources/icons/bin.png")
|
||||
|
||||
return thumbnl
|
||||
|
||||
def nonImageOrVideoIcon(self, fullPath):
|
||||
if fullPath.lower().endswith( ('.desktop',) ):
|
||||
return self.parseDesktopFiles(fullPath)
|
||||
else:
|
||||
thumbPth = self.getSystemThumbnail(fullPath, self.systemIconImageWxH[0])
|
||||
return self.createIconImageBuffer(thumbPth, self.systemIconImageWxH)
|
||||
|
||||
def createIconImageBuffer(self, path, wxh):
|
||||
try:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, wxh[0], wxh[1], False)
|
||||
return gtk.Image.new_from_pixbuf(pixbuf)
|
||||
except Exception as e:
|
||||
return gtk.Image.new_from_file("resources/icons/bin.png")
|
||||
|
||||
def parseDesktopFiles(self, fullPath):
|
||||
try:
|
||||
xdgObj = DesktopEntry(fullPath)
|
||||
icon = xdgObj.getIcon()
|
||||
iconsDirs = "/usr/share/icons"
|
||||
altIconPath = ""
|
||||
|
||||
if "steam" in icon: # This whole thing is iffy at best but I want my damn icons!!
|
||||
if "steam" in icon:
|
||||
steamIconsDir = self.usrHome + "/.thumbnails/steam_icons/"
|
||||
name = xdgObj.getName()
|
||||
fileHash = hashlib.sha256(str.encode(name)).hexdigest()
|
||||
@ -95,10 +90,10 @@ class Icon:
|
||||
if isdir(steamIconsDir) == False:
|
||||
os.mkdir(steamIconsDir)
|
||||
|
||||
hashImgpth = steamIconsDir + fileHash + ".jpg"
|
||||
if isfile(hashImgpth) == True:
|
||||
hashImgPth = steamIconsDir + fileHash + ".jpg"
|
||||
if isfile(hashImgPth) == True:
|
||||
# Use video sizes since headers are bigger
|
||||
return self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
||||
return self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||
|
||||
execStr = xdgObj.getExec()
|
||||
parts = execStr.split("steam://rungameid/")
|
||||
@ -113,13 +108,13 @@ class Icon:
|
||||
# use the bottom logic
|
||||
|
||||
imageLink = "https://steamcdn-a.akamaihd.net/steam/apps/" + id + "/header.jpg"
|
||||
proc = subprocess.Popen(["wget", "-O", hashImgpth, imageLink])
|
||||
proc = subprocess.Popen(["wget", "-O", hashImgPth, imageLink])
|
||||
proc.wait()
|
||||
|
||||
# Use video sizes since headers are bigger
|
||||
return self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
||||
return self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||
elif os.path.exists(icon):
|
||||
return self.createIconImageBuffer(icon, self.systemIconImageWxH)
|
||||
return self.createIconImageBuffer(icon, self.systemIconImageWH)
|
||||
else:
|
||||
for (dirpath, dirnames, filenames) in os.walk(iconsDirs):
|
||||
for file in filenames:
|
||||
@ -128,22 +123,46 @@ class Icon:
|
||||
altIconPath = dirpath + "/" + file
|
||||
break
|
||||
|
||||
return self.createIconImageBuffer(altIconPath, self.systemIconImageWxH)
|
||||
return self.createIconImageBuffer(altIconPath, self.systemIconImageWH)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
|
||||
def getSystemThumbnail(self, filename, size):
|
||||
final_filename = ""
|
||||
try:
|
||||
iconPath = None
|
||||
if os.path.exists(filename):
|
||||
file = gio.File.new_for_path(filename)
|
||||
info = file.query_info('standard::icon' , 0 , gio.Cancellable())
|
||||
icon = info.get_icon().get_names()[0]
|
||||
iconTheme = gtk.IconTheme.get_default()
|
||||
iconFile = iconTheme.lookup_icon(icon , size , 0)
|
||||
|
||||
icon_theme = gtk.IconTheme.get_default()
|
||||
icon_file = icon_theme.lookup_icon(icon , size , 0)
|
||||
if icon_file != None:
|
||||
final_filename = icon_file.get_filename()
|
||||
if iconFile != None:
|
||||
iconPath = iconFile.get_filename()
|
||||
return self.createIconImageBuffer(iconPath, self.systemIconImageWH)
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
return final_filename
|
||||
|
||||
def generateVideoThumbnail(self, fullPath, hashImgpth):
|
||||
proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgpth])
|
||||
def createIconImageBuffer(self, path, wxh):
|
||||
try:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, wxh[0], wxh[1], False)
|
||||
except Exception as e:
|
||||
return None
|
||||
|
||||
return gtk.Image.new_from_pixbuf(pixbuf)
|
||||
|
||||
|
||||
def generateVideoThumbnail(self, fullPath, hashImgPth):
|
||||
try:
|
||||
proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgPth])
|
||||
proc.wait()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
@ -52,16 +52,9 @@ class Settings:
|
||||
styleContext.add_provider_for_screen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||
|
||||
window.set_app_paintable(True)
|
||||
window.connect("draw", self.area_draw)
|
||||
monitors = self.getMonitorData(screen)
|
||||
window.resize(monitors[0].width, monitors[0].height)
|
||||
|
||||
def area_draw(self, widget, cr):
|
||||
cr.set_source_rgba(0.0, 0.0, 0.0, 0.64)
|
||||
cr.set_operator(cairo.OPERATOR_SOURCE)
|
||||
cr.paint()
|
||||
cr.set_operator(cairo.OPERATOR_OVER)
|
||||
|
||||
def getMonitorData(self, screen):
|
||||
monitors = []
|
||||
for m in range(screen.get_n_monitors()):
|
||||
|
@ -29,5 +29,8 @@ class Main:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main = Main()
|
||||
gtk.main()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
@ -17,7 +17,6 @@
|
||||
</object>
|
||||
<object class="GtkWindow" id="Window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="default_width">800</property>
|
||||
<property name="default_height">600</property>
|
||||
<property name="type_hint">desktop</property>
|
||||
@ -101,6 +100,8 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="selection_mode">multiple</property>
|
||||
<property name="columns">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -115,10 +116,10 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopoverMenu" id="iconControlsWindow">
|
||||
<object class="GtkPopover" id="iconControlsWindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="relative_to">Desktop</property>
|
||||
<property name="position">right</property>
|
||||
<property name="relative_to">popOutBttn</property>
|
||||
<property name="position">bottom</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
@ -212,9 +213,6 @@
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="submenu">main</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="webViewer">
|
||||
|
@ -34,3 +34,55 @@ cell:focus {
|
||||
outline-style: solid;
|
||||
outline-color: rgba(0, 232, 255, 0.64);
|
||||
}
|
||||
|
||||
|
||||
/* Ivonview and children default color */
|
||||
.view {
|
||||
background-color: rgba(0, 0, 0, 0.22);
|
||||
color: #ebebeb;
|
||||
}
|
||||
|
||||
|
||||
/* Hover over color when not selected */
|
||||
.view:hover {
|
||||
box-shadow: inset 0 0 0 9999px alpha(rgba(0, 232, 255, 0.64), 0.54);
|
||||
}
|
||||
|
||||
/* Handles the icon selection hover and selected hover color. */
|
||||
.view:selected,
|
||||
.view:selected:hover {
|
||||
box-shadow: inset 0 0 0 9999px rgba(15, 134, 13, 0.49);
|
||||
}
|
||||
|
||||
/* Rubberband coloring */
|
||||
.rubberband,
|
||||
rubberband,
|
||||
flowbox rubberband,
|
||||
treeview.view rubberband,
|
||||
.content-view rubberband,
|
||||
.content-view .rubberband,
|
||||
XfdesktopIconView.view .rubberband {
|
||||
border: 1px solid #6c6c6c;
|
||||
background-color: rgba(21, 158, 167, 0.57);
|
||||
}
|
||||
|
||||
XfdesktopIconView.view:active {
|
||||
background-color: rgba(172, 102, 21, 1);
|
||||
}
|
||||
|
||||
|
||||
XfdesktopIconView.view {
|
||||
border-radius: 4px;
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
XfdesktopIconView.view:active {
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
XfdesktopIconView.view .rubberband {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
@ -41,9 +41,16 @@ class Grid:
|
||||
self.desktop.set_text_column(1)
|
||||
self.desktop.connect("item-activated", self.iconLeftClickEventManager)
|
||||
self.desktop.connect("button_press_event", self.iconRightClickEventManager, (self.desktop,))
|
||||
self.desktop.connect("selection-changed", self.setIconSelectionArray, (self.desktop,))
|
||||
|
||||
self.vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
||||
self.imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
||||
self.copyCutArry = []
|
||||
|
||||
|
||||
self.gtkLock = False # Thread checks for gtkLock
|
||||
self.threadLock = False # Gtk checks for thread lock
|
||||
self.toWorkPool = [] # Thread fills pool and gtk empties it
|
||||
|
||||
self.setIconViewDir(newPath)
|
||||
|
||||
@ -81,18 +88,56 @@ class Grid:
|
||||
files.sort()
|
||||
|
||||
files = dirPaths + vids + images + desktop + files
|
||||
self.generateDirectoryGrid(path, files)
|
||||
self.generateDirectoryGrid(path, files) # Run helper thread...
|
||||
glib.idle_add(self.addToGrid, (file,)) # This must stay in the main thread b/c
|
||||
# gtk isn't thread safe/aware So, we
|
||||
# make a sad lil thread hot potato 'game'
|
||||
# out of this process.
|
||||
|
||||
|
||||
@threaded
|
||||
def generateDirectoryGrid(self, dirPath, files):
|
||||
# NOTE: We'll be passing pixbuf after retreval to keep Icon.py file more
|
||||
# universaly usable. We can just remove get_pixbuf to get a gtk.Image type
|
||||
storageQue = []
|
||||
for file in files:
|
||||
image = Icon(self.settings).createIcon(dirPath, file)
|
||||
# NOTE: Passing pixbuf after retreval to keep Icon.py file more universaly usable.
|
||||
# We can just remove get_pixbuf to get a gtk image
|
||||
glib.idle_add(self.addToGrid, (image.get_pixbuf(), file,))
|
||||
|
||||
if len(storageQue) > 0:
|
||||
for dataSet in storageQue:
|
||||
self.toWorkPool.append(dataSet)
|
||||
|
||||
self.toWorkPool.append([image.get_pixbuf(), file])
|
||||
self.threadLock = False
|
||||
self.gtkLock = True
|
||||
storageQue.clear()
|
||||
|
||||
|
||||
def addToGrid(self, args):
|
||||
self.store.append([args[0], args[1]])
|
||||
# NOTE: Returning true tells gtk to check again in the future when idle.
|
||||
# False ends checks and "continues normal flow"
|
||||
files = args[0]
|
||||
|
||||
if len(self.toWorkPool) > 0:
|
||||
for dataSet in self.toWorkPool:
|
||||
self.store.append(dataSet)
|
||||
|
||||
if len(self.store) == len(files): # Vonfirm processed all files and cleanup
|
||||
self.gtkLock = False
|
||||
self.threadLock = False
|
||||
self.toWorkPool.clear()
|
||||
return False
|
||||
# Check again when idle. If nothing else is updating
|
||||
# this function gets called immediatly so we play hot potato
|
||||
else:
|
||||
self.toWorkPool.clear()
|
||||
self.gtkLock = False
|
||||
self.threadLock = True
|
||||
return True
|
||||
|
||||
def setIconSelectionArray(self, widget, data=None):
|
||||
os.system('cls||clear')
|
||||
print(data)
|
||||
|
||||
def iconLeftClickEventManager(self, widget, item):
|
||||
try:
|
||||
@ -121,8 +166,6 @@ class Grid:
|
||||
popover = self.builder.get_object("iconControlsWindow")
|
||||
popover.show_all()
|
||||
popover.popup()
|
||||
print(popover)
|
||||
|
||||
# # NOTE: Need to change name of listview box...
|
||||
# children = widget.get_children()[0].get_children()
|
||||
# fileName = children[1].get_text()
|
||||
|
@ -28,66 +28,61 @@ class Icon:
|
||||
|
||||
self.GTK_ORIENTATION = settings.returnIconImagePos()
|
||||
self.usrHome = settings.returnUserHome()
|
||||
self.iconContainerWxH = settings.returnContainerWH()
|
||||
self.systemIconImageWxH = settings.returnSystemIconImageWH()
|
||||
self.viIconWxH = settings.returnVIIconWH()
|
||||
self.iconContainerWH = settings.returnContainerWH()
|
||||
self.systemIconImageWH = settings.returnSystemIconImageWH()
|
||||
self.viIconWH = settings.returnVIIconWH()
|
||||
|
||||
|
||||
def createIcon(self, dir, file):
|
||||
fullPath = dir + "/" + file
|
||||
thumbnl = self.getIconImage(file, fullPath)
|
||||
return thumbnl
|
||||
return self.getIconImage(file, fullPath)
|
||||
|
||||
|
||||
def getIconImage(self, file, fullPath):
|
||||
thumbnl = gtk.Image()
|
||||
try:
|
||||
thumbnl = None
|
||||
vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
||||
imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
||||
|
||||
try:
|
||||
if file.lower().endswith(vidsList): # Video thumbnail
|
||||
# Video thumbnail
|
||||
if file.lower().endswith(vidsList):
|
||||
fileHash = hashlib.sha256(str.encode(fullPath)).hexdigest()
|
||||
hashImgpth = self.usrHome + "/.thumbnails/normal/" + fileHash + ".png"
|
||||
hashImgPth = self.usrHome + "/.thumbnails/normal/" + fileHash + ".png"
|
||||
|
||||
if isfile(hashImgpth) == False:
|
||||
self.generateVideoThumbnail(fullPath, hashImgpth)
|
||||
if isfile(hashImgPth) == False:
|
||||
self.generateVideoThumbnail(fullPath, hashImgPth)
|
||||
|
||||
thumbnl = self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
||||
elif file.lower().endswith(imagesList): # Image Icon
|
||||
thumbnl = self.createIconImageBuffer(fullPath, self.viIconWxH)
|
||||
else: # System icons
|
||||
thumbnl = self.nonImageOrVideoIcon(fullPath)
|
||||
thumbnl = self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||
# Image Icon
|
||||
elif file.lower().endswith(imagesList):
|
||||
thumbnl = self.createIconImageBuffer(fullPath, self.viIconWH)
|
||||
# .desktop file parsing
|
||||
elif fullPath.lower().endswith( ('.desktop',) ):
|
||||
thumbnl = self.parseDesktopFiles(fullPath)
|
||||
# System icons
|
||||
else:
|
||||
thumbnl = self.getSystemThumbnail(fullPath, self.systemIconImageWH[0])
|
||||
|
||||
if thumbnl == None: # If no icon, try stock file icon...
|
||||
thumbnl = gtk.Image.new_from_icon_name("gtk-file", gtk.IconSize.LARGE_TOOLBAR)
|
||||
|
||||
if thumbnl == None: # If no icon whatsoever, return internal default
|
||||
thumbnl = gtk.Image.new_from_file("resources/icons/bin.png")
|
||||
|
||||
return thumbnl
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return gtk.Image.new_from_file("resources/icons/bin.png")
|
||||
|
||||
if thumbnl == None: # If no system icon, try stock file icon...
|
||||
thumbnl = gtk.Image.new_from_icon_name("gtk-file", gtk.IconSize.LARGE_TOOLBAR)
|
||||
if thumbnl == None:
|
||||
thumbnl = gtk.Image.new_from_file("resources/icons/bin.png")
|
||||
|
||||
return thumbnl
|
||||
|
||||
def nonImageOrVideoIcon(self, fullPath):
|
||||
if fullPath.lower().endswith( ('.desktop',) ):
|
||||
return self.parseDesktopFiles(fullPath)
|
||||
else:
|
||||
thumbPth = self.getSystemThumbnail(fullPath, self.systemIconImageWxH[0])
|
||||
return self.createIconImageBuffer(thumbPth, self.systemIconImageWxH)
|
||||
|
||||
def createIconImageBuffer(self, path, wxh):
|
||||
try:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, wxh[0], wxh[1], False)
|
||||
return gtk.Image.new_from_pixbuf(pixbuf)
|
||||
except Exception as e:
|
||||
return gtk.Image.new_from_file("resources/icons/bin.png")
|
||||
|
||||
def parseDesktopFiles(self, fullPath):
|
||||
try:
|
||||
xdgObj = DesktopEntry(fullPath)
|
||||
icon = xdgObj.getIcon()
|
||||
iconsDirs = "/usr/share/icons"
|
||||
altIconPath = ""
|
||||
|
||||
if "steam" in icon: # This whole thing is iffy at best but I want my damn icons!!
|
||||
if "steam" in icon:
|
||||
steamIconsDir = self.usrHome + "/.thumbnails/steam_icons/"
|
||||
name = xdgObj.getName()
|
||||
fileHash = hashlib.sha256(str.encode(name)).hexdigest()
|
||||
@ -95,10 +90,10 @@ class Icon:
|
||||
if isdir(steamIconsDir) == False:
|
||||
os.mkdir(steamIconsDir)
|
||||
|
||||
hashImgpth = steamIconsDir + fileHash + ".jpg"
|
||||
if isfile(hashImgpth) == True:
|
||||
hashImgPth = steamIconsDir + fileHash + ".jpg"
|
||||
if isfile(hashImgPth) == True:
|
||||
# Use video sizes since headers are bigger
|
||||
return self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
||||
return self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||
|
||||
execStr = xdgObj.getExec()
|
||||
parts = execStr.split("steam://rungameid/")
|
||||
@ -113,13 +108,13 @@ class Icon:
|
||||
# use the bottom logic
|
||||
|
||||
imageLink = "https://steamcdn-a.akamaihd.net/steam/apps/" + id + "/header.jpg"
|
||||
proc = subprocess.Popen(["wget", "-O", hashImgpth, imageLink])
|
||||
proc = subprocess.Popen(["wget", "-O", hashImgPth, imageLink])
|
||||
proc.wait()
|
||||
|
||||
# Use video sizes since headers are bigger
|
||||
return self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
||||
return self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||
elif os.path.exists(icon):
|
||||
return self.createIconImageBuffer(icon, self.systemIconImageWxH)
|
||||
return self.createIconImageBuffer(icon, self.systemIconImageWH)
|
||||
else:
|
||||
for (dirpath, dirnames, filenames) in os.walk(iconsDirs):
|
||||
for file in filenames:
|
||||
@ -128,22 +123,46 @@ class Icon:
|
||||
altIconPath = dirpath + "/" + file
|
||||
break
|
||||
|
||||
return self.createIconImageBuffer(altIconPath, self.systemIconImageWxH)
|
||||
return self.createIconImageBuffer(altIconPath, self.systemIconImageWH)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
|
||||
def getSystemThumbnail(self, filename, size):
|
||||
final_filename = ""
|
||||
try:
|
||||
iconPath = None
|
||||
if os.path.exists(filename):
|
||||
file = gio.File.new_for_path(filename)
|
||||
info = file.query_info('standard::icon' , 0 , gio.Cancellable())
|
||||
icon = info.get_icon().get_names()[0]
|
||||
iconTheme = gtk.IconTheme.get_default()
|
||||
iconFile = iconTheme.lookup_icon(icon , size , 0)
|
||||
|
||||
icon_theme = gtk.IconTheme.get_default()
|
||||
icon_file = icon_theme.lookup_icon(icon , size , 0)
|
||||
if icon_file != None:
|
||||
final_filename = icon_file.get_filename()
|
||||
if iconFile != None:
|
||||
iconPath = iconFile.get_filename()
|
||||
return self.createIconImageBuffer(iconPath, self.systemIconImageWH)
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
return final_filename
|
||||
|
||||
def generateVideoThumbnail(self, fullPath, hashImgpth):
|
||||
proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgpth])
|
||||
def createIconImageBuffer(self, path, wxh):
|
||||
try:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, wxh[0], wxh[1], False)
|
||||
except Exception as e:
|
||||
return None
|
||||
|
||||
return gtk.Image.new_from_pixbuf(pixbuf)
|
||||
|
||||
|
||||
def generateVideoThumbnail(self, fullPath, hashImgPth):
|
||||
try:
|
||||
proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgPth])
|
||||
proc.wait()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
@ -52,16 +52,9 @@ class Settings:
|
||||
styleContext.add_provider_for_screen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||
|
||||
window.set_app_paintable(True)
|
||||
window.connect("draw", self.area_draw)
|
||||
monitors = self.getMonitorData(screen)
|
||||
window.resize(monitors[0].width, monitors[0].height)
|
||||
|
||||
def area_draw(self, widget, cr):
|
||||
cr.set_source_rgba(0.0, 0.0, 0.0, 0.64)
|
||||
cr.set_operator(cairo.OPERATOR_SOURCE)
|
||||
cr.paint()
|
||||
cr.set_operator(cairo.OPERATOR_OVER)
|
||||
|
||||
def getMonitorData(self, screen):
|
||||
monitors = []
|
||||
for m in range(screen.get_n_monitors()):
|
||||
|
Loading…
Reference in New Issue
Block a user