Fixes for Qt6

This commit is contained in:
Jeremy Rimpo
2021-12-06 03:46:18 -06:00
parent f95b09a4a9
commit 18461fee44
4 changed files with 403 additions and 240 deletions
+244 -115
View File
File diff suppressed because it is too large Load Diff
+65 -44
View File
@@ -1,39 +1,44 @@
from pathlib import Path
from PyQt5.QtCore import QCoreApplication, qCritical
from PyQt5.QtGui import QOpenGLTexture
from PyQt6.QtCore import QCoreApplication, qCritical
from PyQt6.QtOpenGL import QOpenGLTexture
from . import DDSDefinitions
from .glstuff import GLTextureFormat
class DDSReadException(Exception):
"""Thrown if there was an error reading a DDS file"""
pass
ddsCubemapFaces = { DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEX: QOpenGLTexture.CubeMapPositiveX,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEX: QOpenGLTexture.CubeMapNegativeX,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEY: QOpenGLTexture.CubeMapPositiveY,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEY: QOpenGLTexture.CubeMapNegativeY,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEZ: QOpenGLTexture.CubeMapPositiveZ,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEZ: QOpenGLTexture.CubeMapNegativeZ }
ddsCubemapFaces = {
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEX: QOpenGLTexture.CubeMapFace.CubeMapPositiveX,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEX: QOpenGLTexture.CubeMapFace.CubeMapNegativeX,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEY: QOpenGLTexture.CubeMapFace.CubeMapPositiveY,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEY: QOpenGLTexture.CubeMapFace.CubeMapNegativeY,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_POSITIVEZ: QOpenGLTexture.CubeMapFace.CubeMapPositiveZ,
DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP_NEGATIVEZ: QOpenGLTexture.CubeMapFace.CubeMapNegativeZ}
class DDSFile:
def __init__(self, fileName):
self.fileName = fileName
self.header = DDSDefinitions.DDS_HEADER()
self.dxt10Header = None
self.glFormat = None
self.glFormat: GLTextureFormat = None
self.data = None
self.isCubemap = None
def load(self):
with Path(self.fileName).open('rb') as file:
magicNumber = file.read(4)
if magicNumber != DDSDefinitions.DDS_MAGIC_NUMBER:
qCritical(self.__tr("Magic number mismatch."))
raise DDSReadException()
self.header.fromStream(file)
if self.header.ddspf.dwFlags & DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_FOURCC:
fourCC = self.header.ddspf.dwFourCC
if fourCC == b"DX10":
@@ -41,12 +46,12 @@ class DDSFile:
self.dxt10Header.fromStream(file)
else:
fourCC = None
self.glFormat = DDSDefinitions.getGLFormat(self.header.ddspf, self.dxt10Header)
self.data = []
# Do this once per layer/mip level whatever, (times one per scanline if uncompressed). Also, potentially recompute this based on the format and size in case writers lie.
#self.data.append(file.read(self.header.dwPitchOrLinearSize))
# self.data.append(file.read(self.header.dwPitchOrLinearSize))
layerCount = 1
if self.header.dwCaps2 & DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP:
self.isCubemap = True
@@ -56,13 +61,14 @@ class DDSFile:
layerCount += 1
else:
self.isCubemap = False
for layer in range(layerCount):
nextWidth = self.header.dwWidth
nextHeight = self.header.dwHeight
mipCount = self.mipLevels()
for level in range(mipCount):
if self.header.ddspf.dwFlags & (DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_ALPHA | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_RGB | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_YUV | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_LUMINANCE):
if self.header.ddspf.dwFlags & (
DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_ALPHA | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_RGB | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_YUV | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_LUMINANCE):
size = nextWidth * nextHeight * ((self.header.ddspf.dwRGBBitCount + 7) // 8)
elif fourCC:
if self.dxt10Header:
@@ -73,7 +79,7 @@ class DDSFile:
self.data.append(file.read(size))
nextWidth = max(nextWidth // 2, 1)
nextHeight = max(nextHeight // 2, 1)
def getDescription(self):
format = ""
# DX10 header says the format enum
@@ -82,39 +88,45 @@ class DDSFile:
# Pixel Format says the FourCC
elif self.header.ddspf.dwFlags & DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_FOURCC:
fourCC = self.header.ddspf.dwFourCC
format = self.__tr("{0} (equivalent to {1})").format(fourCC.decode('ascii'), DDSDefinitions.fourCCToDXGI(fourCC).name.replace("DXGI_FORMAT_", ""))
format = self.__tr("{0} (equivalent to {1})").format(fourCC.decode('ascii'),
DDSDefinitions.fourCCToDXGI(fourCC).name.replace(
"DXGI_FORMAT_", ""))
# We've got bitmasks for the colour channels
else:
# This could be prettier if there was logic to detect that certain common bitmasks represented things more easily represented, like RGBA8
if self.header.ddspf.dwFlags & (DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_RGB | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_YUV):
format += self.__tr("Red bitmask {0}, Green bitmask {1}, Blue bitmask {2}").format(self.header.ddspf.dwRBitMask.hex().upper(), self.header.ddspf.dwGBitMask.hex().upper(), self.header.ddspf.dwBBitMask.hex().upper())
if self.header.ddspf.dwFlags & (
DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_RGB | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_YUV):
format += self.__tr("Red bitmask {0}, Green bitmask {1}, Blue bitmask {2}").format(
self.header.ddspf.dwRBitMask.hex().upper(), self.header.ddspf.dwGBitMask.hex().upper(),
self.header.ddspf.dwBBitMask.hex().upper())
if self.header.ddspf.dwFlags & DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_LUMINANCE:
if format != "":
format += ", "
format += self.__tr("Luminance bitmask {0}").format(self.header.ddspf.dwRBitMask.hex().upper())
if self.header.ddspf.dwFlags & (DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_ALPHA | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_ALPHAPIXELS):
if self.header.ddspf.dwFlags & (
DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_ALPHA | DDSDefinitions.DDS_PIXELFORMAT.Flags.DDPF_ALPHAPIXELS):
if format != "":
format += ", "
format += self.__tr("Alpha bitmask {0}").format(self.header.ddspf.dwABitMask.hex().upper())
size = self.__tr("{0}×{1}").format(self.header.dwWidth, self.header.dwHeight)
dimensions = self.__tr("Cubemap") if self.isCubemap else self.__tr("2D")
mipmaps = self.__tr("Mipmapped") if self.mipLevels() != 1 else self.__tr("No mipmaps")
return self.__tr("{0}, {1} {2}, {3}").format(format, size, dimensions, mipmaps)
def mipLevels(self):
if self.header.dwFlags & DDSDefinitions.DDS_HEADER.Flags.DDSD_MIPMAPCOUNT:
return self.header.dwMipMapCount
else:
return 1
def asQOpenGLTexture(self, gl, context):
if not self.data:
return
if self.glFormat.requirements:
minVersion, extensions = self.glFormat.requirements
glVersion = (gl.glGetIntegerv(gl.GL_MAJOR_VERSION), gl.glGetIntegerv(gl.GL_MINOR_VERSION))
@@ -127,15 +139,15 @@ class DDSFile:
if not compatible:
qCritical(self.__tr("OpenGL driver incompatible with texture format."))
return None
if self.header.dwCaps2 & DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP:
texture = QOpenGLTexture(QOpenGLTexture.TargetCubeMap)
texture = QOpenGLTexture(QOpenGLTexture.Target.TargetCubeMap)
if self.header.dwWidth != self.header.dwHeight:
qCritical(self.__tr("Cubemap faces must be square"))
return None
else:
# Assume GL_TEXTURE_2D for now
texture = QOpenGLTexture(QOpenGLTexture.Target2D)
texture = QOpenGLTexture(QOpenGLTexture.Target.Target2D)
# Assume single layer for now
# self.texture.setLayers(1)
mipCount = self.mipLevels()
@@ -143,9 +155,9 @@ class DDSFile:
texture.setMipLevels(mipCount)
texture.setMipLevelRange(0, mipCount - 1)
texture.setSize(self.header.dwWidth, self.header.dwHeight)
texture.setFormat(self.glFormat.internalFormat)
texture.setFormat(QOpenGLTexture.TextureFormat(self.glFormat.internalFormat))
texture.allocateStorage()
if self.header.dwCaps2 & DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP:
# Lisa hasn't whipped David Wang into shape yet. At least there are fewer bugs than under Raja.
# The specific bug has been reported and AMD "will try to reproduce it soon"
@@ -158,11 +170,19 @@ class DDSFile:
for i in range(mipCount):
if self.glFormat.compressed:
if not noDSA:
texture.setCompressedData(i, 0, ddsCubemapFaces[face], len(self.data[faceIndex * mipCount + i]), self.data[faceIndex * mipCount + i])
texture.setCompressedData(i, 0, ddsCubemapFaces[face],
len(self.data[faceIndex * mipCount + i]),
self.data[faceIndex * mipCount + i])
else:
gl.glCompressedTexSubImage2D(ddsCubemapFaces[face], i, 0, 0, max(self.header.dwWidth // 2 ** i, 1), max(self.header.dwHeight // 2 ** i, 1), self.glFormat.internalFormat, len(self.data[faceIndex * mipCount + i]), self.data[faceIndex * mipCount + i])
gl.glCompressedTexSubImage2D(ddsCubemapFaces[face], i, 0, 0,
max(self.header.dwWidth // 2 ** i, 1),
max(self.header.dwHeight // 2 ** i, 1),
self.glFormat.internalFormat,
len(self.data[faceIndex * mipCount + i]),
self.data[faceIndex * mipCount + i])
else:
texture.setData(i, 0, ddsCubemapFaces[face], self.glFormat.format, self.glFormat.type, self.glFormat.converter(self.data[faceIndex * mipCount + i]))
texture.setData(i, 0, ddsCubemapFaces[face], self.glFormat.format, self.glFormat.type,
self.glFormat.converter(self.data[faceIndex * mipCount + i]))
faceIndex += 1
if noDSA:
texture.release()
@@ -171,15 +191,16 @@ class DDSFile:
if self.glFormat.compressed:
texture.setCompressedData(i, 0, len(self.data[i]), self.data[i])
else:
texture.setData(i, 0, self.glFormat.format, self.glFormat.type, self.glFormat.converter(self.data[i]))
texture.setWrapMode(QOpenGLTexture.ClampToEdge)
texture.setData(i, 0, self.glFormat.format, self.glFormat.type,
self.glFormat.converter(self.data[i]))
texture.setWrapMode(QOpenGLTexture.WrapMode.ClampToEdge)
if self.glFormat.samplerType != "F":
# integer textures can't be filtered
texture.setMinMagFilters(QOpenGLTexture.NearestMipMapNearest, QOpenGLTexture.Nearest)
texture.setMinMagFilters(QOpenGLTexture.Filter.NearestMipMapNearest, QOpenGLTexture.Filter.Nearest)
return texture
def __tr(self, str):
return QCoreApplication.translate("DDSFile", str)
+8 -4
View File
@@ -1,5 +1,6 @@
from enum import IntEnum
class GL_IMAGE_FORMAT(IntEnum):
GL_BYTE = 0x1400
GL_UNSIGNED_BYTE = 0x1401
@@ -111,9 +112,9 @@ class GL_IMAGE_FORMAT(IntEnum):
GL_RGBA16F = 0x881A
GL_RGB16F = 0x881B
GL_R11F_G11F_B10F = 0x8C3A
GL_UNSIGNED_INT_10F_11F_11F_REV_EXT = 0x8C3B # EXT_packed_float
GL_UNSIGNED_INT_10F_11F_11F_REV_EXT = 0x8C3B # EXT_packed_float
GL_RGB9_E5 = 0x8C3D
GL_UNSIGNED_INT_5_9_9_9_REV_EXT = 0x8C3E # EXT_texture_shared_exponent
GL_UNSIGNED_INT_5_9_9_9_REV_EXT = 0x8C3E # EXT_texture_shared_exponent
GL_SRGB = 0x8C40
GL_SRGB8 = 0x8C41
GL_SRGB_ALPHA = 0x8C42
@@ -173,12 +174,13 @@ class GL_IMAGE_FORMAT(IntEnum):
GL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278
GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279
class GLTextureFormat:
def __init__(self, requirements, internalFormat, compressed):
self.requirements = requirements
self.internalFormat = internalFormat
self.compressed = compressed
if internalFormat.name.endswith("UI"):
self.samplerType = "UI"
elif internalFormat.name.endswith("I"):
@@ -186,12 +188,14 @@ class GLTextureFormat:
else:
self.samplerType = "F"
class CompressedGLTextureFormat(GLTextureFormat):
def __init__(self, requirements, internalFormat):
super().__init__(requirements, internalFormat, True)
class UncompressedGLTextureFormat(GLTextureFormat):
def __init__(self, requirements, internalFormat, format, type, converter = None):
def __init__(self, requirements, internalFormat, format, type, converter=None):
super().__init__(requirements, internalFormat, False)
self.format = format
self.type = type
+86 -77
View File
@@ -2,9 +2,12 @@ import struct
import sys
import threading
from PyQt5.QtCore import QCoreApplication, qDebug, Qt
from PyQt5.QtGui import QColor, QOpenGLBuffer, QOpenGLContext, QOpenGLDebugLogger, QOpenGLShader, QOpenGLShaderProgram, QOpenGLTexture, QOpenGLVersionProfile, QOpenGLVertexArrayObject, QSurfaceFormat
from PyQt5.QtWidgets import QCheckBox, QDialog, QGridLayout, QLabel, QOpenGLWidget, QPushButton, QWidget
from PyQt6.QtCore import QCoreApplication, qDebug, Qt
from PyQt6.QtGui import QColor, QOpenGLContext, QSurfaceFormat, QWindow
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
from PyQt6.QtWidgets import QCheckBox, QDialog, QGridLayout, QLabel, QPushButton, QWidget, QColorDialog
from PyQt6.QtOpenGL import QOpenGLBuffer, QOpenGLDebugLogger, QOpenGLShader, QOpenGLShaderProgram, QOpenGLTexture, \
QOpenGLVersionProfile, QOpenGLVertexArrayObject, QOpenGLFunctions_4_1_Core, QOpenGLVersionFunctionsFactory
from DDS.DDSFile import DDSFile
@@ -136,61 +139,61 @@ void main()
vertices = [
# vertex coordinates texture coordinates
-1.0, -1.0, 0.5, 1.0, 0.0, 1.0,
-1.0, 1.0, 0.5, 1.0, 0.0, 0.0,
1.0, 1.0, 0.5, 1.0, 1.0, 0.0,
-1.0, -1.0, 0.5, 1.0, 0.0, 1.0,
1.0, 1.0, 0.5, 1.0, 1.0, 0.0,
1.0, -1.0, 0.5, 1.0, 1.0, 1.0,
-1.0, -1.0, 0.5, 1.0, 0.0, 1.0,
-1.0, 1.0, 0.5, 1.0, 0.0, 0.0,
1.0, 1.0, 0.5, 1.0, 1.0, 0.0,
-1.0, -1.0, 0.5, 1.0, 0.0, 1.0,
1.0, 1.0, 0.5, 1.0, 1.0, 0.0,
1.0, -1.0, 0.5, 1.0, 1.0, 1.0,
]
glVersionProfile = QOpenGLVersionProfile()
glVersionProfile.setVersion(2, 1)
class DDSWidget(QOpenGLWidget):
def __init__(self, ddsFile, debugContext = False, parent = None, f = Qt.WindowFlags()):
super(DDSWidget, self).__init__(parent, f)
def __init__(self, ddsFile, debugContext=False, parent=None, flags=Qt.WindowType(0)):
super(DDSWidget, self).__init__(parent, flags=flags)
self.ddsFile = ddsFile
self.clean = True
self.logger = None
self.program = None
self.transparecyProgram = None
self.texture = None
self.vbo = None
self.vao = None
self.backgroundColour = None
if debugContext:
format = QSurfaceFormat()
format.setOption(QSurfaceFormat.DebugContext)
format.setOption(QSurfaceFormat.FormatOption.DebugContext)
self.setFormat(format)
self.logger = QOpenGLDebugLogger(self)
def __del__(self):
self.cleanup()
def __dtor__(self):
self.cleanup()
def initializeGL(self):
if self.logger:
self.logger.initialize()
self.logger.messageLogged.connect(lambda message: qDebug(self.__tr("OpenGL debug message: {0}").fomat(message.message())))
self.logger.messageLogged.connect(
lambda message: qDebug(self.__tr("OpenGL debug message: {0}").fomat(message.message())))
self.logger.startLogging()
gl = QOpenGLContext.currentContext().versionFunctions(glVersionProfile)
gl = QOpenGLVersionFunctionsFactory.get(glVersionProfile)
QOpenGLContext.currentContext().aboutToBeDestroyed.connect(self.cleanup)
self.clean = False
fragmentShader = None
vertexShader = vertexShader2D
if self.ddsFile.isCubemap:
@@ -205,79 +208,79 @@ class DDSWidget(QOpenGLWidget):
fragmentShader = fragmentShaderUInt
else:
fragmentShader = fragmentShaderSInt
self.program = QOpenGLShaderProgram(self)
self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertexShader)
self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragmentShader)
self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Vertex, vertexShader)
self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Fragment, fragmentShader)
self.program.bindAttributeLocation("position", 0)
self.program.bindAttributeLocation("texCoordIn", 1)
self.program.link()
self.transparecyProgram = QOpenGLShaderProgram(self)
self.transparecyProgram.addShaderFromSourceCode(QOpenGLShader.Vertex, transparencyVS)
self.transparecyProgram.addShaderFromSourceCode(QOpenGLShader.Fragment, transparencyFS)
self.transparecyProgram.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Vertex, transparencyVS)
self.transparecyProgram.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Fragment, transparencyFS)
self.transparecyProgram.bindAttributeLocation("position", 0)
self.transparecyProgram.link()
self.vao = QOpenGLVertexArrayObject(self)
vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao)
self.vbo = QOpenGLBuffer(QOpenGLBuffer.VertexBuffer)
self.vbo = QOpenGLBuffer(QOpenGLBuffer.Type.VertexBuffer)
self.vbo.create()
self.vbo.bind()
theBytes = struct.pack("%sf" % len(vertices), *vertices)
self.vbo.allocate(theBytes, len(theBytes))
gl.glEnableVertexAttribArray(0)
gl.glEnableVertexAttribArray(1)
gl.glVertexAttribPointer(0, 4, gl.GL_FLOAT, False, 6 * 4, 0)
gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, False, 6 * 4, 4 * 4)
self.texture = self.ddsFile.asQOpenGLTexture(gl, QOpenGLContext.currentContext())
def resizeGL(self, w, h):
aspectRatioTex = self.texture.width() / self.texture.height() if self.texture else 1.0
aspectRatioWidget = w / h
ratioRatio = aspectRatioTex / aspectRatioWidget
self.program.bind()
self.program.setUniformValue("aspectRatioRatio", ratioRatio)
self.program.release()
def paintGL(self):
gl = QOpenGLContext.currentContext().versionFunctions(glVersionProfile)
gl = QOpenGLVersionFunctionsFactory.get(glVersionProfile)
vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao)
# Draw checkerboard so transparency is obvious
self.transparecyProgram.bind()
if self.backgroundColour and self.backgroundColour.isValid():
self.transparecyProgram.setUniformValue("backgroundColour", self.backgroundColour)
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
self.transparecyProgram.release()
self.program.bind()
if self.texture:
self.texture.bind()
gl.glEnable(gl.GL_BLEND)
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
if self.texture:
self.texture.release()
self.program.release()
def cleanup(self):
if not self.clean:
self.makeCurrent()
self.program = None
self.transparecyProgram = None
if self.texture:
@@ -287,22 +290,22 @@ class DDSWidget(QOpenGLWidget):
self.vbo = None
self.vao.destroy()
self.vao = None
self.doneCurrent()
self.clean = True
def setBackgroundColour(self, colour):
self.backgroundColour = colour
def getBackgroundColour(self):
return self.backgroundColour
def __tr(self, str):
return QCoreApplication.translate("DDSWidget", str)
class DDSPreview(mobase.IPluginPreview):
def __init__(self):
super().__init__()
self.__organizer = None
@@ -324,15 +327,16 @@ class DDSPreview(mobase.IPluginPreview):
return mobase.VersionInfo(1, 0, 0, 0)
def settings(self):
return [mobase.PluginSetting("log gl errors", self.__tr("If enabled, log OpenGL errors and debug messages. May decrease performance."), False),
return [mobase.PluginSetting("log gl errors", self.__tr(
"If enabled, log OpenGL errors and debug messages. May decrease performance."), False),
mobase.PluginSetting("background r", self.__tr("Red channel of background colour"), 0),
mobase.PluginSetting("background g", self.__tr("Green channel of background colour"), 0),
mobase.PluginSetting("background b", self.__tr("Blue channel of background colour"), 0),
mobase.PluginSetting("background a", self.__tr("Alpha channel of background colour"), 0)]
def supportedExtensions(self):
return ["dds"]
def genFilePreview(self, fileName, maxSize):
ddsFile = DDSFile(fileName)
ddsFile.load()
@@ -342,41 +346,46 @@ class DDSPreview(mobase.IPluginPreview):
# Label grows before button
layout.setColumnStretch(0, 1)
layout.addWidget(self.__makeLabel(ddsFile), 1, 0, 1, 1)
ddsWidget = DDSWidget(ddsFile, self.__organizer.pluginSetting(self.name(), "log gl errors"))
layout.addWidget(ddsWidget, 0, 0, 1, 2)
layout.addWidget(self.__makeColourButton(ddsWidget), 1, 1, 1, 1)
widget = QWidget()
widget.setLayout(layout)
return widget
def __tr(self, str):
return QCoreApplication.translate("DDSPreview", str)
def __makeLabel(self, ddsFile):
label = QLabel(ddsFile.getDescription())
label.setWordWrap(True)
label.setTextInteractionFlags(Qt.TextSelectableByMouse)
label.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
return label
def __makeColourButton(self, ddsWidget):
button = QPushButton(self.__tr("Pick background colour"))
savedColour = QColor(self.__organizer.pluginSetting(self.name(), "background r"), self.__organizer.pluginSetting(self.name(), "background g"), self.__organizer.pluginSetting(self.name(), "background b"), self.__organizer.pluginSetting(self.name(), "background a"))
savedColour = QColor(self.__organizer.pluginSetting(self.name(), "background r"),
self.__organizer.pluginSetting(self.name(), "background g"),
self.__organizer.pluginSetting(self.name(), "background b"),
self.__organizer.pluginSetting(self.name(), "background a"))
ddsWidget.setBackgroundColour(savedColour)
def pickColour(unused):
newColour = QColorDialog.getColor(ddsWidget.getBackgroundColour(), button, "Background colour", QColorDialog.ShowAlphaChannel)
newColour = QColorDialog.getColor(ddsWidget.getBackgroundColour(), button, "Background colour",
QColorDialog.ColorDialogOption.ShowAlphaChannel)
if newColour.isValid():
ddsWidget.setBackgroundColour(newColour)
self.__organizer.setPluginSetting(self.name(), "background r", newColour.red())
self.__organizer.setPluginSetting(self.name(), "background g", newColour.green())
self.__organizer.setPluginSetting(self.name(), "background b", newColour.blue())
self.__organizer.setPluginSetting(self.name(), "background a", newColour.alpha())
button.clicked.connect(pickColour)
return button
def createPlugin():
return DDSPreview()