1 from __future__ import absolute_import
2 from __future__ import division
5 from wx import glcanvas
7 OpenGL.ERROR_CHECKING = False
8 from OpenGL.GL import *
10 from Cura.gui.util import opengl
12 class glGuiControl(object):
13 def __init__(self, parent, pos):
15 self._base = parent._base
17 self._size = (0,0, 1, 1)
18 self._parent.add(self)
20 def setSize(self, x, y, w, h):
21 self._size = (x, y, w, h)
29 def updateLayout(self):
32 class glGuiContainer(glGuiControl):
33 def __init__(self, parent, pos):
34 self._glGuiControlList = []
35 glGuiLayoutButtons(self)
36 super(glGuiContainer, self).__init__(parent, pos)
39 self._glGuiControlList.append(ctrl)
42 def OnMouseDown(self, x, y):
43 for ctrl in self._glGuiControlList:
44 if ctrl.OnMouseDown(x, y):
47 def OnMouseMotion(self, x, y):
49 for ctrl in self._glGuiControlList:
50 if ctrl.OnMouseMotion(x, y):
55 for ctrl in self._glGuiControlList:
58 def updateLayout(self):
60 for ctrl in self._glGuiControlList:
63 class glGuiPanel(glcanvas.GLCanvas):
64 def __init__(self, parent):
65 attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24, glcanvas.WX_GL_STENCIL_SIZE, 8)
66 glcanvas.GLCanvas.__init__(self, parent, style=wx.WANTS_CHARS, attribList = attribList)
69 self._container = None
70 self._container = glGuiContainer(self, (0,0))
72 self._context = glcanvas.GLContext(self)
73 self._glButtonsTexture = None
76 wx.EVT_PAINT(self, self._OnGuiPaint)
77 wx.EVT_SIZE(self, self._OnSize)
78 wx.EVT_ERASE_BACKGROUND(self, self._OnEraseBackground)
79 wx.EVT_LEFT_DOWN(self, self._OnGuiMouseLeftDown)
80 wx.EVT_MOTION(self, self._OnGuiMouseMotion)
81 wx.EVT_CHAR(self, self.OnKeyChar)
82 wx.EVT_KILL_FOCUS(self, self.OnFocusLost)
84 def OnKeyChar(self, e):
87 def OnFocusLost(self, e):
91 def _OnGuiMouseLeftDown(self,e):
93 if self._container.OnMouseDown(e.GetX(), e.GetY()):
95 self.OnMouseLeftDown(e)
97 def _OnGuiMouseMotion(self,e):
99 if not self._container.OnMouseMotion(e.GetX(), e.GetY()):
100 self.OnMouseMotion(e)
102 def _OnGuiPaint(self, e):
103 h = self.GetSize().GetHeight()
104 w = self.GetSize().GetWidth()
105 oldButtonSize = self._buttonSize
109 self._buttonSize = 48
111 self._buttonSize = 64
113 self._buttonSize = 80
115 self._buttonSize = 96
116 if self._buttonSize != oldButtonSize:
117 self._container.updateLayout()
119 dc = wx.PaintDC(self)
120 self.SetCurrent(self._context)
127 if self._glButtonsTexture is None:
128 self._glButtonsTexture = opengl.loadGLTexture('glButtons.png')
130 glDisable(GL_DEPTH_TEST)
132 glDisable(GL_LIGHTING)
133 glColor4ub(255,255,255,255)
135 glMatrixMode(GL_PROJECTION)
137 size = self.GetSize()
138 glOrtho(0, size.GetWidth()-1, size.GetHeight()-1, 0, -1000.0, 1000.0)
139 glMatrixMode(GL_MODELVIEW)
142 self._container.draw()
144 def _OnEraseBackground(self,event):
145 #Workaround for windows background redraw flicker.
149 self._container.setSize(0, 0, self.GetSize().GetWidth(), self.GetSize().GetHeight())
150 self._container.updateLayout()
153 def OnMouseLeftDown(self,e):
155 def OnMouseMotion(self, e):
157 def OnPaint(self, e):
161 if self._container is not None:
162 self._container.add(ctrl)
164 class glGuiLayoutButtons(object):
165 def __init__(self, parent):
166 self._parent = parent
167 self._parent._layout = self
170 bs = self._parent._base._buttonSize
171 x0, y0, w, h = self._parent.getSize()
173 for ctrl in self._parent._glGuiControlList:
176 x = w + pos[0] * gridSize - bs * 0.2
178 x = pos[0] * gridSize + bs * 0.2
180 y = h + pos[1] * gridSize - bs * 0.2
182 y = pos[1] * gridSize + bs * 0.2
183 ctrl.setSize(x, y, gridSize, gridSize)
185 def getLayoutSize(self):
186 _, _, w, h = self._parent.getSize()
189 class glGuiLayoutGrid(object):
190 def __init__(self, parent):
191 self._parent = parent
192 self._parent._layout = self
196 borderSize = self._parent._base._buttonSize * 0.2
197 x0, y0, w, h = self._parent.getSize()
202 for ctrl in self._parent._glGuiControlList:
204 w, h = ctrl.getMinSize()
208 widths[x] = max(widths[x], w)
212 heights[y] = max(heights[y], h)
213 for ctrl in self._parent._glGuiControlList:
217 for n in xrange(0, x):
221 for n in xrange(0, y):
225 ctrl.setSize(x1, y1, widths[x], heights[y])
226 self._size = sum(widths.values()) + borderSize * 2, sum(heights.values()) + borderSize * 2
228 def getLayoutSize(self):
231 class glButton(glGuiControl):
232 def __init__(self, parent, imageID, tooltip, pos, callback):
233 super(glButton, self).__init__(parent, pos)
234 self._tooltip = tooltip
235 self._parent = parent
236 self._imageID = imageID
237 self._callback = callback
238 self._selected = False
242 def setSelected(self, value):
243 self._selected = value
245 def setHidden(self, value):
248 def getSelected(self):
249 return self._selected
251 def getMinSize(self):
252 return self._base._buttonSize, self._base._buttonSize
254 def _getPixelPos(self):
255 x0, y0, w, h = self.getSize()
256 return x0 + w / 2, y0 + h / 2
262 cx = (self._imageID % 4) / 4
263 cy = int(self._imageID / 4) / 4
264 bs = self._base._buttonSize
265 pos = self._getPixelPos()
268 glTranslatef(pos[0], pos[1], 0)
269 glBindTexture(GL_TEXTURE_2D, self._base._glButtonsTexture)
270 glEnable(GL_TEXTURE_2D)
276 glScalef(bs * scale, bs * scale, bs * scale)
277 glColor4ub(255,255,255,255)
279 glTexCoord2f(cx+0.25, cy)
280 glVertex2f( 0.5,-0.5)
282 glVertex2f(-0.5,-0.5)
283 glTexCoord2f(cx, cy+0.25)
284 glVertex2f(-0.5, 0.5)
285 glTexCoord2f(cx+0.25, cy+0.25)
286 glVertex2f( 0.5, 0.5)
288 glDisable(GL_TEXTURE_2D)
290 glColor4ub(0,0,0,255)
291 glTranslatef(0, -0.55, 0)
292 opengl.glDrawStringCenter(self._tooltip)
295 def _checkHit(self, x, y):
298 bs = self.getMinSize()[0]
299 pos = self._getPixelPos()
300 return -bs * 0.5 <= x - pos[0] <= bs * 0.5 and -bs * 0.5 <= y - pos[1] <= bs * 0.5
302 def OnMouseMotion(self, x, y):
303 if self._checkHit(x, y):
309 def OnMouseDown(self, x, y):
310 if self._checkHit(x, y):
315 class glFrame(glGuiContainer):
316 def __init__(self, parent, pos):
317 super(glFrame, self).__init__(parent, pos)
318 self._selected = False
322 def setSelected(self, value):
323 self._selected = value
325 def setHidden(self, value):
328 def getSelected(self):
329 return self._selected
331 def getMinSize(self):
332 return self._base._buttonSize, self._base._buttonSize
334 def _getPixelPos(self):
335 x0, y0, w, h = self.getSize()
342 bs = self._parent._buttonSize
343 pos = self._getPixelPos()
346 glTranslatef(pos[0], pos[1], 0)
347 glBindTexture(GL_TEXTURE_2D, self._parent._glButtonsTexture)
348 glDisable(GL_TEXTURE_2D)
350 size = self._layout.getLayoutSize()
351 glColor4ub(255,255,255,128)
354 glVertex2f( size[0], 0)
358 glVertex2f( 0, size[1])
360 glVertex2f( size[0], size[1])
362 glDisable(GL_TEXTURE_2D)
364 #Draw the controls on the frame
365 super(glFrame, self).draw()
367 def _checkHit(self, x, y):
370 pos = self._getPixelPos()
371 w, h = self._layout.getLayoutSize()
372 return 0 <= x - pos[0] <= w and 0 <= y - pos[1] <= h
374 def OnMouseMotion(self, x, y):
375 super(glFrame, self).OnMouseMotion(x, y)
376 if self._checkHit(x, y):
382 def OnMouseDown(self, x, y):
383 if self._checkHit(x, y):
384 super(glFrame, self).OnMouseDown(x, y)
388 class glLabel(glGuiControl):
389 def __init__(self, parent, label, pos):
391 super(glLabel, self).__init__(parent, pos)
393 def getMinSize(self):
394 w, h = opengl.glGetStringSize(self._label)
397 def _getPixelPos(self):
398 x0, y0, w, h = self.getSize()
402 pos = self._getPixelPos()
405 glTranslatef(pos[0], pos[1], 0)
407 size = self.getMinSize()
408 glColor4ub(255,255,255,128)
411 glVertex2f( size[0], 0)
415 glVertex2f( 0, size[1])
417 glVertex2f( size[0], size[1])
420 glTranslate(5, size[1] - 5, 0)
421 glColor4ub(0,0,0,255)
422 opengl.glDrawStringLeft(self._label)
425 def _checkHit(self, x, y):
428 def OnMouseMotion(self, x, y):
431 def OnMouseDown(self, x, y):