Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add transparency toggle #9

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 62 additions & 32 deletions src/DDSPreview.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,11 @@
glVersionProfile.setVersion(2, 1)

class DDSWidget(QOpenGLWidget):
def __init__(self, ddsFile, debugContext = False, parent = None, f = Qt.WindowFlags()):
def __init__(self, ddsPreview, ddsFile, debugContext = False, parent = None, f = Qt.WindowFlags()):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not keen on creating a cyclic dependency between DDSWidget and DDSPreview. Technically, it's possible to find uses for a DDS widget other than the preview, so we might want to move it out of this plugin into a library and make the plugin depend on that library. You can break the cycle by creating a class that holds the current options which both the widget and preview plugin have a reference to an instance of.

super(DDSWidget, self).__init__(parent, f)


self.ddsPreview = ddsPreview

self.ddsFile = ddsFile

self.clean = True
Expand All @@ -166,8 +168,6 @@ def __init__(self, ddsFile, debugContext = False, parent = None, f = Qt.WindowFl
self.vbo = None
self.vao = None

self.backgroundColour = None

if debugContext:
format = QSurfaceFormat()
format.setOption(QSurfaceFormat.DebugContext)
Expand Down Expand Up @@ -252,9 +252,10 @@ def paintGL(self):

# Draw checkerboard so transparency is obvious
self.transparecyProgram.bind()

if self.backgroundColour and self.backgroundColour.isValid():
self.transparecyProgram.setUniformValue("backgroundColour", self.backgroundColour)

backgroundColour = self.ddsPreview.getBackgroundColour()
if backgroundColour and backgroundColour.isValid():
self.transparecyProgram.setUniformValue("backgroundColour", backgroundColour)

gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

Expand All @@ -264,9 +265,12 @@ def paintGL(self):

if self.texture:
self.texture.bind()

gl.glEnable(gl.GL_BLEND)
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)

if self.ddsPreview.getTransparency():
gl.glEnable(gl.GL_BLEND)
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
else:
gl.glDisable(gl.GL_BLEND)

gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

Expand All @@ -291,12 +295,6 @@ def cleanup(self):
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)

Expand All @@ -311,6 +309,12 @@ def init(self, organizer):
self.__organizer = organizer
return True

def pluginSetting(self, name):
return self.__organizer.pluginSetting(self.name(), name)

def setPluginSetting(self, name, value):
self.__organizer.setPluginSetting(self.name(), name, value)

def name(self):
return "DDS Preview Plugin"

Expand All @@ -328,7 +332,8 @@ def settings(self):
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)]
mobase.PluginSetting("background a", self.__tr("Alpha channel of background colour"), 0),
mobase.PluginSetting("transparency", self.__tr("If enabled, transparency will be displayed."), True)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be more technically accurate to refer to it as alpha rather than transparency or translucency. The whole reason this PR is necessary is that it's not always transparency data.


def supportedExtensions(self):
return ["dds"]
Expand All @@ -342,12 +347,13 @@ def genFilePreview(self, fileName, maxSize):
# 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)


ddsWidget = DDSWidget(self, ddsFile, self.__organizer.pluginSetting(self.name(), "log gl errors"))
layout.addWidget(ddsWidget, 0, 0, 1, 3)

layout.addWidget(self.__makeColourButton(ddsWidget), 1, 2, 1, 1)
layout.addWidget(self.__makeToggleTransparencyButton(ddsWidget), 1, 1, 1, 1)

widget = QWidget()
widget.setLayout(layout)
return widget
Expand All @@ -363,20 +369,44 @@ def __makeLabel(self, ddsFile):

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"))
ddsWidget.setBackgroundColour(savedColour)


def pickColour(unused):
newColour = QColorDialog.getColor(ddsWidget.getBackgroundColour(), button, "Background colour", QColorDialog.ShowAlphaChannel)
newColour = QColorDialog.getColor(self.getBackgroundColour(), button, "Background colour", QColorDialog.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())
self.setPluginSetting("background r", newColour.red())
self.setPluginSetting("background g", newColour.green())
self.setPluginSetting("background b", newColour.blue())
self.setPluginSetting("background a", newColour.alpha())
ddsWidget.update()

button.clicked.connect(pickColour)
return button

def __makeToggleTransparencyButton(self, ddsWidget):
def getButtonText():
if self.getTransparency():
return self.__tr("Disable Transparency")
else:
return self.__tr("Enable Transparency")

button = QPushButton(getButtonText())
# Since every conflicting mod gets its own button, the text needs to be updated when the page is changed.
button.showEvent = lambda _: button.setText(getButtonText())

def toggleTransparency(unused):
transparency = not self.getTransparency()
self.setPluginSetting("transparency", transparency)
ddsWidget.update()
button.setText(getButtonText())

button.clicked.connect(toggleTransparency)
return button

def getBackgroundColour(self):
return QColor(self.pluginSetting("background r"), self.pluginSetting("background g"), self.pluginSetting("background b"), self.pluginSetting("background a"))

def getTransparency(self):
return self.pluginSetting("transparency")

def createPlugin():
return DDSPreview()
29 changes: 22 additions & 7 deletions src/DDSPreview_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,40 +71,55 @@
<context>
<name>DDSPreview</name>
<message>
<location filename="DDSPreview.py" line="321"/>
<location filename="DDSPreview.py" line="325"/>
<source>Lets you preview DDS files by actually uploading them to the GPU.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="327"/>
<location filename="DDSPreview.py" line="331"/>
<source>If enabled, log OpenGL errors and debug messages. May decrease performance.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="328"/>
<location filename="DDSPreview.py" line="332"/>
<source>Red channel of background colour</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="329"/>
<location filename="DDSPreview.py" line="333"/>
<source>Green channel of background colour</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="330"/>
<location filename="DDSPreview.py" line="334"/>
<source>Blue channel of background colour</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="331"/>
<location filename="DDSPreview.py" line="335"/>
<source>Alpha channel of background colour</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="365"/>
<location filename="DDSPreview.py" line="336"/>
<source>If enabled, transparency will be displayed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="371"/>
<source>Pick background colour</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="388"/>
<source>Disable Transparency</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="DDSPreview.py" line="390"/>
<source>Enable Transparency</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DDSWidget</name>
Expand Down