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.
|
Pytop is a Gtk + Python gui to have a custom desktop interface.
|
||||||
|
|
||||||
# Notes
|
# Notes
|
||||||
```sudo apt-get install python3 steamcmd
|
```sudo apt-get install python3 wget steamcmd```
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -29,5 +29,8 @@ class Main:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main = Main()
|
try:
|
||||||
gtk.main()
|
main = Main()
|
||||||
|
gtk.main()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
</object>
|
</object>
|
||||||
<object class="GtkWindow" id="Window">
|
<object class="GtkWindow" id="Window">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="window_position">center</property>
|
|
||||||
<property name="default_width">800</property>
|
<property name="default_width">800</property>
|
||||||
<property name="default_height">600</property>
|
<property name="default_height">600</property>
|
||||||
<property name="type_hint">desktop</property>
|
<property name="type_hint">desktop</property>
|
||||||
@ -101,6 +100,8 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="margin">6</property>
|
<property name="margin">6</property>
|
||||||
|
<property name="selection_mode">multiple</property>
|
||||||
|
<property name="columns">6</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@ -115,10 +116,10 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkPopoverMenu" id="iconControlsWindow">
|
<object class="GtkPopover" id="iconControlsWindow">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="relative_to">Desktop</property>
|
<property name="relative_to">popOutBttn</property>
|
||||||
<property name="position">right</property>
|
<property name="position">bottom</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -212,9 +213,6 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="submenu">main</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkPopover" id="webViewer">
|
<object class="GtkPopover" id="webViewer">
|
||||||
|
@ -34,3 +34,55 @@ cell:focus {
|
|||||||
outline-style: solid;
|
outline-style: solid;
|
||||||
outline-color: rgba(0, 232, 255, 0.64);
|
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.set_text_column(1)
|
||||||
self.desktop.connect("item-activated", self.iconLeftClickEventManager)
|
self.desktop.connect("item-activated", self.iconLeftClickEventManager)
|
||||||
self.desktop.connect("button_press_event", self.iconRightClickEventManager, (self.desktop,))
|
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.vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
||||||
self.imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
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)
|
self.setIconViewDir(newPath)
|
||||||
|
|
||||||
@ -81,18 +88,56 @@ class Grid:
|
|||||||
files.sort()
|
files.sort()
|
||||||
|
|
||||||
files = dirPaths + vids + images + desktop + files
|
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
|
@threaded
|
||||||
def generateDirectoryGrid(self, dirPath, files):
|
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:
|
for file in files:
|
||||||
image = Icon(self.settings).createIcon(dirPath, file)
|
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
|
if len(storageQue) > 0:
|
||||||
glib.idle_add(self.addToGrid, (image.get_pixbuf(), file,))
|
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):
|
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):
|
def iconLeftClickEventManager(self, widget, item):
|
||||||
try:
|
try:
|
||||||
@ -121,8 +166,6 @@ class Grid:
|
|||||||
popover = self.builder.get_object("iconControlsWindow")
|
popover = self.builder.get_object("iconControlsWindow")
|
||||||
popover.show_all()
|
popover.show_all()
|
||||||
popover.popup()
|
popover.popup()
|
||||||
print(popover)
|
|
||||||
|
|
||||||
# # NOTE: Need to change name of listview box...
|
# # NOTE: Need to change name of listview box...
|
||||||
# children = widget.get_children()[0].get_children()
|
# children = widget.get_children()[0].get_children()
|
||||||
# fileName = children[1].get_text()
|
# fileName = children[1].get_text()
|
||||||
|
@ -23,127 +23,146 @@ def threaded(fn):
|
|||||||
|
|
||||||
class Icon:
|
class Icon:
|
||||||
def __init__(self, settings):
|
def __init__(self, settings):
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.thubnailGen = self.settings.getThumbnailGenerator()
|
self.thubnailGen = self.settings.getThumbnailGenerator()
|
||||||
|
|
||||||
self.GTK_ORIENTATION = settings.returnIconImagePos()
|
self.GTK_ORIENTATION = settings.returnIconImagePos()
|
||||||
self.usrHome = settings.returnUserHome()
|
self.usrHome = settings.returnUserHome()
|
||||||
self.iconContainerWxH = settings.returnContainerWH()
|
self.iconContainerWH = settings.returnContainerWH()
|
||||||
self.systemIconImageWxH = settings.returnSystemIconImageWH()
|
self.systemIconImageWH = settings.returnSystemIconImageWH()
|
||||||
self.viIconWxH = settings.returnVIIconWH()
|
self.viIconWH = settings.returnVIIconWH()
|
||||||
|
|
||||||
|
|
||||||
def createIcon(self, dir, file):
|
def createIcon(self, dir, file):
|
||||||
fullPath = dir + "/" + file
|
fullPath = dir + "/" + file
|
||||||
thumbnl = self.getIconImage(file, fullPath)
|
return self.getIconImage(file, fullPath)
|
||||||
return thumbnl
|
|
||||||
|
|
||||||
def getIconImage(self, file, fullPath):
|
def getIconImage(self, file, fullPath):
|
||||||
thumbnl = gtk.Image()
|
|
||||||
vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
|
||||||
imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if file.lower().endswith(vidsList): # Video thumbnail
|
thumbnl = None
|
||||||
|
vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
||||||
|
imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
||||||
|
|
||||||
|
# Video thumbnail
|
||||||
|
if file.lower().endswith(vidsList):
|
||||||
fileHash = hashlib.sha256(str.encode(fullPath)).hexdigest()
|
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:
|
if isfile(hashImgPth) == False:
|
||||||
self.generateVideoThumbnail(fullPath, hashImgpth)
|
self.generateVideoThumbnail(fullPath, hashImgPth)
|
||||||
|
|
||||||
thumbnl = self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
thumbnl = self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||||
elif file.lower().endswith(imagesList): # Image Icon
|
# Image Icon
|
||||||
thumbnl = self.createIconImageBuffer(fullPath, self.viIconWxH)
|
elif file.lower().endswith(imagesList):
|
||||||
else: # System icons
|
thumbnl = self.createIconImageBuffer(fullPath, self.viIconWH)
|
||||||
thumbnl = self.nonImageOrVideoIcon(fullPath)
|
# .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:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
return gtk.Image.new_from_file("resources/icons/bin.png")
|
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 parseDesktopFiles(self, fullPath):
|
||||||
|
try:
|
||||||
|
xdgObj = DesktopEntry(fullPath)
|
||||||
|
icon = xdgObj.getIcon()
|
||||||
|
iconsDirs = "/usr/share/icons"
|
||||||
|
altIconPath = ""
|
||||||
|
|
||||||
|
if "steam" in icon:
|
||||||
|
steamIconsDir = self.usrHome + "/.thumbnails/steam_icons/"
|
||||||
|
name = xdgObj.getName()
|
||||||
|
fileHash = hashlib.sha256(str.encode(name)).hexdigest()
|
||||||
|
|
||||||
|
if isdir(steamIconsDir) == False:
|
||||||
|
os.mkdir(steamIconsDir)
|
||||||
|
|
||||||
|
hashImgPth = steamIconsDir + fileHash + ".jpg"
|
||||||
|
if isfile(hashImgPth) == True:
|
||||||
|
# Use video sizes since headers are bigger
|
||||||
|
return self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||||
|
|
||||||
|
execStr = xdgObj.getExec()
|
||||||
|
parts = execStr.split("steam://rungameid/")
|
||||||
|
id = parts[len(parts) - 1]
|
||||||
|
|
||||||
|
# NOTE: Can try this logic instead...
|
||||||
|
# if command exists use it instead of header image
|
||||||
|
# if "steamcmd app_info_print id":
|
||||||
|
# proc = subprocess.Popen(["steamcmd", "app_info_print", id])
|
||||||
|
# proc.wait()
|
||||||
|
# else:
|
||||||
|
# use the bottom logic
|
||||||
|
|
||||||
|
imageLink = "https://steamcdn-a.akamaihd.net/steam/apps/" + id + "/header.jpg"
|
||||||
|
proc = subprocess.Popen(["wget", "-O", hashImgPth, imageLink])
|
||||||
|
proc.wait()
|
||||||
|
|
||||||
|
# Use video sizes since headers are bigger
|
||||||
|
return self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||||
|
elif os.path.exists(icon):
|
||||||
|
return self.createIconImageBuffer(icon, self.systemIconImageWH)
|
||||||
|
else:
|
||||||
|
for (dirpath, dirnames, filenames) in os.walk(iconsDirs):
|
||||||
|
for file in filenames:
|
||||||
|
appNM = "application-x-" + icon
|
||||||
|
if appNM in file:
|
||||||
|
altIconPath = dirpath + "/" + file
|
||||||
|
break
|
||||||
|
|
||||||
|
return self.createIconImageBuffer(altIconPath, self.systemIconImageWH)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def getSystemThumbnail(self, filename, size):
|
||||||
|
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)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
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):
|
def createIconImageBuffer(self, path, wxh):
|
||||||
try:
|
try:
|
||||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, wxh[0], wxh[1], False)
|
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:
|
except Exception as e:
|
||||||
return gtk.Image.new_from_file("resources/icons/bin.png")
|
return None
|
||||||
|
|
||||||
def parseDesktopFiles(self, fullPath):
|
return gtk.Image.new_from_pixbuf(pixbuf)
|
||||||
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!!
|
|
||||||
steamIconsDir = self.usrHome + "/.thumbnails/steam_icons/"
|
|
||||||
name = xdgObj.getName()
|
|
||||||
fileHash = hashlib.sha256(str.encode(name)).hexdigest()
|
|
||||||
|
|
||||||
if isdir(steamIconsDir) == False:
|
def generateVideoThumbnail(self, fullPath, hashImgPth):
|
||||||
os.mkdir(steamIconsDir)
|
try:
|
||||||
|
proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgPth])
|
||||||
hashImgpth = steamIconsDir + fileHash + ".jpg"
|
|
||||||
if isfile(hashImgpth) == True:
|
|
||||||
# Use video sizes since headers are bigger
|
|
||||||
return self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
|
||||||
|
|
||||||
execStr = xdgObj.getExec()
|
|
||||||
parts = execStr.split("steam://rungameid/")
|
|
||||||
id = parts[len(parts) - 1]
|
|
||||||
|
|
||||||
# NOTE: Can try this logic instead...
|
|
||||||
# if command exists use it instead of header image
|
|
||||||
# if "steamcmd app_info_print id":
|
|
||||||
# proc = subprocess.Popen(["steamcmd", "app_info_print", id])
|
|
||||||
# proc.wait()
|
|
||||||
# else:
|
|
||||||
# use the bottom logic
|
|
||||||
|
|
||||||
imageLink = "https://steamcdn-a.akamaihd.net/steam/apps/" + id + "/header.jpg"
|
|
||||||
proc = subprocess.Popen(["wget", "-O", hashImgpth, imageLink])
|
|
||||||
proc.wait()
|
proc.wait()
|
||||||
|
except Exception as e:
|
||||||
# Use video sizes since headers are bigger
|
print(e)
|
||||||
return self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
|
||||||
elif os.path.exists(icon):
|
|
||||||
return self.createIconImageBuffer(icon, self.systemIconImageWxH)
|
|
||||||
else:
|
|
||||||
for (dirpath, dirnames, filenames) in os.walk(iconsDirs):
|
|
||||||
for file in filenames:
|
|
||||||
appNM = "application-x-" + icon
|
|
||||||
if appNM in file:
|
|
||||||
altIconPath = dirpath + "/" + file
|
|
||||||
break
|
|
||||||
|
|
||||||
return self.createIconImageBuffer(altIconPath, self.systemIconImageWxH)
|
|
||||||
|
|
||||||
def getSystemThumbnail(self, filename, size):
|
|
||||||
final_filename = ""
|
|
||||||
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]
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
return final_filename
|
|
||||||
|
|
||||||
def generateVideoThumbnail(self, fullPath, hashImgpth):
|
|
||||||
proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgpth])
|
|
||||||
proc.wait()
|
|
||||||
|
@ -52,16 +52,9 @@ class Settings:
|
|||||||
styleContext.add_provider_for_screen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_USER)
|
styleContext.add_provider_for_screen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||||
|
|
||||||
window.set_app_paintable(True)
|
window.set_app_paintable(True)
|
||||||
window.connect("draw", self.area_draw)
|
|
||||||
monitors = self.getMonitorData(screen)
|
monitors = self.getMonitorData(screen)
|
||||||
window.resize(monitors[0].width, monitors[0].height)
|
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):
|
def getMonitorData(self, screen):
|
||||||
monitors = []
|
monitors = []
|
||||||
for m in range(screen.get_n_monitors()):
|
for m in range(screen.get_n_monitors()):
|
||||||
|
@ -29,5 +29,8 @@ class Main:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main = Main()
|
try:
|
||||||
gtk.main()
|
main = Main()
|
||||||
|
gtk.main()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
</object>
|
</object>
|
||||||
<object class="GtkWindow" id="Window">
|
<object class="GtkWindow" id="Window">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="window_position">center</property>
|
|
||||||
<property name="default_width">800</property>
|
<property name="default_width">800</property>
|
||||||
<property name="default_height">600</property>
|
<property name="default_height">600</property>
|
||||||
<property name="type_hint">desktop</property>
|
<property name="type_hint">desktop</property>
|
||||||
@ -101,6 +100,8 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="margin">6</property>
|
<property name="margin">6</property>
|
||||||
|
<property name="selection_mode">multiple</property>
|
||||||
|
<property name="columns">6</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@ -115,10 +116,10 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkPopoverMenu" id="iconControlsWindow">
|
<object class="GtkPopover" id="iconControlsWindow">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="relative_to">Desktop</property>
|
<property name="relative_to">popOutBttn</property>
|
||||||
<property name="position">right</property>
|
<property name="position">bottom</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -212,9 +213,6 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="submenu">main</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkPopover" id="webViewer">
|
<object class="GtkPopover" id="webViewer">
|
||||||
|
@ -34,3 +34,55 @@ cell:focus {
|
|||||||
outline-style: solid;
|
outline-style: solid;
|
||||||
outline-color: rgba(0, 232, 255, 0.64);
|
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.set_text_column(1)
|
||||||
self.desktop.connect("item-activated", self.iconLeftClickEventManager)
|
self.desktop.connect("item-activated", self.iconLeftClickEventManager)
|
||||||
self.desktop.connect("button_press_event", self.iconRightClickEventManager, (self.desktop,))
|
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.vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
||||||
self.imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
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)
|
self.setIconViewDir(newPath)
|
||||||
|
|
||||||
@ -81,18 +88,56 @@ class Grid:
|
|||||||
files.sort()
|
files.sort()
|
||||||
|
|
||||||
files = dirPaths + vids + images + desktop + files
|
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
|
@threaded
|
||||||
def generateDirectoryGrid(self, dirPath, files):
|
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:
|
for file in files:
|
||||||
image = Icon(self.settings).createIcon(dirPath, file)
|
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
|
if len(storageQue) > 0:
|
||||||
glib.idle_add(self.addToGrid, (image.get_pixbuf(), file,))
|
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):
|
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):
|
def iconLeftClickEventManager(self, widget, item):
|
||||||
try:
|
try:
|
||||||
@ -121,8 +166,6 @@ class Grid:
|
|||||||
popover = self.builder.get_object("iconControlsWindow")
|
popover = self.builder.get_object("iconControlsWindow")
|
||||||
popover.show_all()
|
popover.show_all()
|
||||||
popover.popup()
|
popover.popup()
|
||||||
print(popover)
|
|
||||||
|
|
||||||
# # NOTE: Need to change name of listview box...
|
# # NOTE: Need to change name of listview box...
|
||||||
# children = widget.get_children()[0].get_children()
|
# children = widget.get_children()[0].get_children()
|
||||||
# fileName = children[1].get_text()
|
# fileName = children[1].get_text()
|
||||||
|
@ -23,127 +23,146 @@ def threaded(fn):
|
|||||||
|
|
||||||
class Icon:
|
class Icon:
|
||||||
def __init__(self, settings):
|
def __init__(self, settings):
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.thubnailGen = self.settings.getThumbnailGenerator()
|
self.thubnailGen = self.settings.getThumbnailGenerator()
|
||||||
|
|
||||||
self.GTK_ORIENTATION = settings.returnIconImagePos()
|
self.GTK_ORIENTATION = settings.returnIconImagePos()
|
||||||
self.usrHome = settings.returnUserHome()
|
self.usrHome = settings.returnUserHome()
|
||||||
self.iconContainerWxH = settings.returnContainerWH()
|
self.iconContainerWH = settings.returnContainerWH()
|
||||||
self.systemIconImageWxH = settings.returnSystemIconImageWH()
|
self.systemIconImageWH = settings.returnSystemIconImageWH()
|
||||||
self.viIconWxH = settings.returnVIIconWH()
|
self.viIconWH = settings.returnVIIconWH()
|
||||||
|
|
||||||
|
|
||||||
def createIcon(self, dir, file):
|
def createIcon(self, dir, file):
|
||||||
fullPath = dir + "/" + file
|
fullPath = dir + "/" + file
|
||||||
thumbnl = self.getIconImage(file, fullPath)
|
return self.getIconImage(file, fullPath)
|
||||||
return thumbnl
|
|
||||||
|
|
||||||
def getIconImage(self, file, fullPath):
|
def getIconImage(self, file, fullPath):
|
||||||
thumbnl = gtk.Image()
|
|
||||||
vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
|
||||||
imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if file.lower().endswith(vidsList): # Video thumbnail
|
thumbnl = None
|
||||||
|
vidsList = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
|
||||||
|
imagesList = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
|
||||||
|
|
||||||
|
# Video thumbnail
|
||||||
|
if file.lower().endswith(vidsList):
|
||||||
fileHash = hashlib.sha256(str.encode(fullPath)).hexdigest()
|
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:
|
if isfile(hashImgPth) == False:
|
||||||
self.generateVideoThumbnail(fullPath, hashImgpth)
|
self.generateVideoThumbnail(fullPath, hashImgPth)
|
||||||
|
|
||||||
thumbnl = self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
thumbnl = self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||||
elif file.lower().endswith(imagesList): # Image Icon
|
# Image Icon
|
||||||
thumbnl = self.createIconImageBuffer(fullPath, self.viIconWxH)
|
elif file.lower().endswith(imagesList):
|
||||||
else: # System icons
|
thumbnl = self.createIconImageBuffer(fullPath, self.viIconWH)
|
||||||
thumbnl = self.nonImageOrVideoIcon(fullPath)
|
# .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:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
return gtk.Image.new_from_file("resources/icons/bin.png")
|
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 parseDesktopFiles(self, fullPath):
|
||||||
|
try:
|
||||||
|
xdgObj = DesktopEntry(fullPath)
|
||||||
|
icon = xdgObj.getIcon()
|
||||||
|
iconsDirs = "/usr/share/icons"
|
||||||
|
altIconPath = ""
|
||||||
|
|
||||||
|
if "steam" in icon:
|
||||||
|
steamIconsDir = self.usrHome + "/.thumbnails/steam_icons/"
|
||||||
|
name = xdgObj.getName()
|
||||||
|
fileHash = hashlib.sha256(str.encode(name)).hexdigest()
|
||||||
|
|
||||||
|
if isdir(steamIconsDir) == False:
|
||||||
|
os.mkdir(steamIconsDir)
|
||||||
|
|
||||||
|
hashImgPth = steamIconsDir + fileHash + ".jpg"
|
||||||
|
if isfile(hashImgPth) == True:
|
||||||
|
# Use video sizes since headers are bigger
|
||||||
|
return self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||||
|
|
||||||
|
execStr = xdgObj.getExec()
|
||||||
|
parts = execStr.split("steam://rungameid/")
|
||||||
|
id = parts[len(parts) - 1]
|
||||||
|
|
||||||
|
# NOTE: Can try this logic instead...
|
||||||
|
# if command exists use it instead of header image
|
||||||
|
# if "steamcmd app_info_print id":
|
||||||
|
# proc = subprocess.Popen(["steamcmd", "app_info_print", id])
|
||||||
|
# proc.wait()
|
||||||
|
# else:
|
||||||
|
# use the bottom logic
|
||||||
|
|
||||||
|
imageLink = "https://steamcdn-a.akamaihd.net/steam/apps/" + id + "/header.jpg"
|
||||||
|
proc = subprocess.Popen(["wget", "-O", hashImgPth, imageLink])
|
||||||
|
proc.wait()
|
||||||
|
|
||||||
|
# Use video sizes since headers are bigger
|
||||||
|
return self.createIconImageBuffer(hashImgPth, self.viIconWH)
|
||||||
|
elif os.path.exists(icon):
|
||||||
|
return self.createIconImageBuffer(icon, self.systemIconImageWH)
|
||||||
|
else:
|
||||||
|
for (dirpath, dirnames, filenames) in os.walk(iconsDirs):
|
||||||
|
for file in filenames:
|
||||||
|
appNM = "application-x-" + icon
|
||||||
|
if appNM in file:
|
||||||
|
altIconPath = dirpath + "/" + file
|
||||||
|
break
|
||||||
|
|
||||||
|
return self.createIconImageBuffer(altIconPath, self.systemIconImageWH)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def getSystemThumbnail(self, filename, size):
|
||||||
|
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)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
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):
|
def createIconImageBuffer(self, path, wxh):
|
||||||
try:
|
try:
|
||||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, wxh[0], wxh[1], False)
|
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:
|
except Exception as e:
|
||||||
return gtk.Image.new_from_file("resources/icons/bin.png")
|
return None
|
||||||
|
|
||||||
def parseDesktopFiles(self, fullPath):
|
return gtk.Image.new_from_pixbuf(pixbuf)
|
||||||
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!!
|
|
||||||
steamIconsDir = self.usrHome + "/.thumbnails/steam_icons/"
|
|
||||||
name = xdgObj.getName()
|
|
||||||
fileHash = hashlib.sha256(str.encode(name)).hexdigest()
|
|
||||||
|
|
||||||
if isdir(steamIconsDir) == False:
|
def generateVideoThumbnail(self, fullPath, hashImgPth):
|
||||||
os.mkdir(steamIconsDir)
|
try:
|
||||||
|
proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgPth])
|
||||||
hashImgpth = steamIconsDir + fileHash + ".jpg"
|
|
||||||
if isfile(hashImgpth) == True:
|
|
||||||
# Use video sizes since headers are bigger
|
|
||||||
return self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
|
||||||
|
|
||||||
execStr = xdgObj.getExec()
|
|
||||||
parts = execStr.split("steam://rungameid/")
|
|
||||||
id = parts[len(parts) - 1]
|
|
||||||
|
|
||||||
# NOTE: Can try this logic instead...
|
|
||||||
# if command exists use it instead of header image
|
|
||||||
# if "steamcmd app_info_print id":
|
|
||||||
# proc = subprocess.Popen(["steamcmd", "app_info_print", id])
|
|
||||||
# proc.wait()
|
|
||||||
# else:
|
|
||||||
# use the bottom logic
|
|
||||||
|
|
||||||
imageLink = "https://steamcdn-a.akamaihd.net/steam/apps/" + id + "/header.jpg"
|
|
||||||
proc = subprocess.Popen(["wget", "-O", hashImgpth, imageLink])
|
|
||||||
proc.wait()
|
proc.wait()
|
||||||
|
except Exception as e:
|
||||||
# Use video sizes since headers are bigger
|
print(e)
|
||||||
return self.createIconImageBuffer(hashImgpth, self.viIconWxH)
|
|
||||||
elif os.path.exists(icon):
|
|
||||||
return self.createIconImageBuffer(icon, self.systemIconImageWxH)
|
|
||||||
else:
|
|
||||||
for (dirpath, dirnames, filenames) in os.walk(iconsDirs):
|
|
||||||
for file in filenames:
|
|
||||||
appNM = "application-x-" + icon
|
|
||||||
if appNM in file:
|
|
||||||
altIconPath = dirpath + "/" + file
|
|
||||||
break
|
|
||||||
|
|
||||||
return self.createIconImageBuffer(altIconPath, self.systemIconImageWxH)
|
|
||||||
|
|
||||||
def getSystemThumbnail(self, filename, size):
|
|
||||||
final_filename = ""
|
|
||||||
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]
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
return final_filename
|
|
||||||
|
|
||||||
def generateVideoThumbnail(self, fullPath, hashImgpth):
|
|
||||||
proc = subprocess.Popen([self.thubnailGen, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgpth])
|
|
||||||
proc.wait()
|
|
||||||
|
@ -52,16 +52,9 @@ class Settings:
|
|||||||
styleContext.add_provider_for_screen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_USER)
|
styleContext.add_provider_for_screen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||||
|
|
||||||
window.set_app_paintable(True)
|
window.set_app_paintable(True)
|
||||||
window.connect("draw", self.area_draw)
|
|
||||||
monitors = self.getMonitorData(screen)
|
monitors = self.getMonitorData(screen)
|
||||||
window.resize(monitors[0].width, monitors[0].height)
|
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):
|
def getMonitorData(self, screen):
|
||||||
monitors = []
|
monitors = []
|
||||||
for m in range(screen.get_n_monitors()):
|
for m in range(screen.get_n_monitors()):
|
||||||
|
Loading…
Reference in New Issue
Block a user