class GLButton(Action, GLFrame): def __init__(self, parent, x=0, y=0, width=None, height=None, img=None, text=None, togglable=False, imgoff=None, action=None, params=None): Action.__init__(self, action, params) GLFrame.__init__(self, parent, x, y, width, height) self.img = img self.setText(text) self.textColor = QColor(0, 0, 0) self.togglable = togglable self.toggled = False self.imgoff = imgoff self.focus = False self.enabled = True self.__initialized__ = False def setText(self, text): self.__text = text self.__computeTextPosition() def geometryChangedEvent(self): self.__computeTextPosition() def actionEvent(self): if self.togglable: self.toggled = not self.toggled def __computeTextPosition(self): if not self.__text is None: qf = QFontMetrics(self.parent.font()) self.__textx = self.x + (self.width - qf.width(self.__text)) / 2 self.__texty = self.y + qf.ascent() + (self.height - qf.height()) / 2 def __del__(self): self.parent.deleteTexture(self.textureId) if self.imgoff: self.parent.deleteTexture(self.textureOffId) def init(self): if not self.__initialized__: self.__initialized__ = True if self.img: self.imgV = QImage(self.img) assert not self.imgV.isNull() if self.width is None: self.width = self.imgV.width() if self.height is None: self.height = self.imgV.height() self.textureId = self.importTexture(self.imgV) if self.imgoff: self.imgoffV = QImage(self.imgoff) self.textureOffId = self.importTexture(self.imgoffV) self.__defaulttoggled = self.toggled self.__defaultenabled = self.enabled else: self.toggled = self.__defaulttoggled self.enabled = self.__defaultenabled def importTexture(self, img): return self.parent.bindTexture(img) def draw(self): if self.visible: glDisable(GL_LIGHTING) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.parent.startScreenCoordinatesSystem() glLineWidth(2) glDisable(GL_LIGHTING) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) if not self.enabled: glColor4f(0.5, 0.5, 0.5, 1.0) else: glColor4f(0, 0, 0, 1.0) self.drawBox() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) if not self.enabled: glColor4f(1.0, 1.0, 1.0, 0.2) elif self.focus: glColor4f(1.0, 1.0, 1.0, 0.6) else: glColor4f(1.0, 1.0, 1.0, 0.4) self.drawBox() if self.img: glTranslatef(0, 0, -0.05) glEnable(GL_TEXTURE_2D) if not self.toggled and self.enabled: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glBindTexture(GL_TEXTURE_2D, self.textureId) else: if self.imgoff: glBindTexture(GL_TEXTURE_2D, self.textureOffId) else: if not self.toggled: glColor4f(1, 1, 1, 0.7) else: if self.enabled: glColor4f(0.2, 0.2, 0.2, 0.5) else: glColor4f(0.2, 0.2, 0.2, 0.3) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) glBindTexture(GL_TEXTURE_2D, self.textureId) glMatrixMode(GL_TEXTURE) glLoadIdentity() self.drawTexBox() glDisable(GL_TEXTURE_2D) glTranslatef(0, 0, 0.05) glLineWidth(1) if not self.__text is None: glColor4f(self.textColor.redF(), self.textColor.greenF(), self.textColor.blueF(), self.textColor.alphaF()) self.parent.drawText(self.__textx, self.__texty, self.__text) glEnable(GL_LIGHTING) self.parent.stopScreenCoordinatesSystem() def mousePressEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): return True return False def mouseMoveEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): self.parent.setFocusWidget(self) return True return False def mouseReleaseEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): self.parent.selectedButton = None self.applyAction() return True return False
class GLTextBox(Action, GLFrame): def __init__(self, parent, text, x=0, y=0, width=100, height=30, action=None, params=None): Action.__init__(self, action, params) GLFrame.__init__(self, parent, x, y, width, height) self.margin = 20 self.textColor = QColor(0, 0, 0) self.focus = False self.enabled = True self.font = QFont() self.font.setBold(True) self.setText(text) self.__initialized__ = False def setText(self, text): if len(text) == 0: return lines = text.split('\n') qf = QFontMetrics(self.font) fmw = max(qf.maxWidth(), 10) nlines = [] w = self.width - 2 * self.margin for line in lines: if qf.width(line) > w: while qf.width(line) > w: for i in xrange(w / fmw, len(line)): if qf.width(line, i) > w: if line[i].isalnum() and line[i - 1].isalnum(): nlines.append(line[0:i - 1] + ( '-' if line[i - 2].isalnum() else '')) line = line[i - 1:] else: nlines.append(line[0:i]) line = line[i:] break nlines.append(QString(line)) else: nlines.append(QString(line)) self.__text = nlines self.__computeTextPosition() def __computeTextPosition(self): if not self.__text is None: qf = QFontMetrics(self.font) self.__textx = self.x + self.margin self.__texty = self.y + self.margin + qf.ascent() + ( self.height - 2 * self.margin - len(self.__text) * qf.height()) / 2 self.__texth = qf.height() def init(self): if not self.__initialized__: self.__initialized__ = True self.__defaultenabled = self.enabled self.__defaultvisible = self.visible else: self.enabled = self.__defaultenabled self.visible = self.__defaultvisible def draw(self): if self.visible: glDisable(GL_LIGHTING) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.parent.startScreenCoordinatesSystem() glLineWidth(2) glDisable(GL_LIGHTING) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glColor4f(0, 0, 0, 1.0) self.drawBox() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glColor4f(1.0, 1.0, 1.0, 0.8) self.drawBox() self.parent.stopScreenCoordinatesSystem() glLineWidth(1) self.mcheckError('1') if not self.__text is None: glColor4f(self.textColor.redF(), self.textColor.greenF(), self.textColor.blueF(), self.textColor.alphaF()) self.mcheckError('2') for i, line in enumerate(self.__text): if len(line) > 0: self.parent.renderText(self.__textx, self.__texty + i * self.__texth, line, self.font) self.mcheckError('n' + str(i) + "'" + line + "'") def mcheckError(self, txt=None): err = glGetError() if err != GL_NO_ERROR: if txt: print txt, ':', print gluErrorString(err) def mousePressEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): return True return False def mouseMoveEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): self.parent.setFocusWidget(self) return True return False def mouseReleaseEvent(self, event): if self.enabled and self.visible and self.containspos(event.pos()): self.parent.selectedButton = None self.applyAction() return True return False