chiark / gitweb /
Merge pull request #349 from smorloc/master
[cura.git] / Cura / gui / util / openglGui.py
1 from __future__ import absolute_import
2 from __future__ import division
3
4 import wx
5 from wx import glcanvas
6 import OpenGL
7 OpenGL.ERROR_CHECKING = False
8 from OpenGL.GL import *
9
10 from Cura.gui.util import opengl
11
12 glButtonsTexture = None
13
14 class glGuiPanel(glcanvas.GLCanvas):
15         def __init__(self, parent):
16                 attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24, glcanvas.WX_GL_STENCIL_SIZE, 8)
17                 glcanvas.GLCanvas.__init__(self, parent, attribList = attribList)
18                 self._parent = parent
19                 self._context = glcanvas.GLContext(self)
20                 self._glGuiControlList = []
21                 self._glButtonsTexture = None
22                 self._buttonSize = 64
23
24                 wx.EVT_PAINT(self, self._OnGuiPaint)
25                 wx.EVT_SIZE(self, self._OnSize)
26                 wx.EVT_ERASE_BACKGROUND(self, self._OnEraseBackground)
27                 wx.EVT_LEFT_DOWN(self, self._OnGuiMouseLeftDown)
28                 wx.EVT_MOTION(self, self._OnGuiMouseMotion)
29
30         def _OnGuiMouseLeftDown(self,e):
31                 for ctrl in self._glGuiControlList:
32                         if ctrl.OnMouseDown(e.GetX(), e.GetY()):
33                                 return
34                 self.OnMouseLeftDown(e)
35
36         def _OnGuiMouseMotion(self,e):
37                 self.Refresh()
38                 handled = False
39                 for ctrl in self._glGuiControlList:
40                         if ctrl.OnMouseMotion(e.GetX(), e.GetY()):
41                                 handled = True
42                 if not handled:
43                         self.OnMouseMotion(e)
44
45         def _OnGuiPaint(self, e):
46                 h = self.GetSize().GetHeight()
47                 w = self.GetSize().GetWidth()
48                 if h / 3 > w / 4:
49                         w = h * 4 / 3
50                 if w < 64 * 10:
51                         self._buttonSize = 48
52                 elif w < 64 * 15:
53                         self._buttonSize = 64
54                 elif w < 64 * 20:
55                         self._buttonSize = 80
56                 else:
57                         self._buttonSize = 96
58
59                 dc = wx.PaintDC(self)
60                 self.SetCurrent(self._context)
61                 self.OnPaint(e)
62                 self._drawGui()
63                 glFlush()
64                 self.SwapBuffers()
65
66         def _drawGui(self):
67                 glDisable(GL_DEPTH_TEST)
68                 glEnable(GL_BLEND)
69                 glDisable(GL_LIGHTING)
70                 glColor4ub(255,255,255,255)
71
72                 glMatrixMode(GL_PROJECTION)
73                 glLoadIdentity()
74                 size = self.GetSize()
75                 glOrtho(0, size.GetWidth()-1, size.GetHeight()-1, 0, -1000.0, 1000.0)
76                 glMatrixMode(GL_MODELVIEW)
77                 glLoadIdentity()
78
79                 for glButton in self._glGuiControlList:
80                         glButton.draw()
81
82         def _OnEraseBackground(self,event):
83                 #Workaround for windows background redraw flicker.
84                 pass
85
86         def _OnSize(self,e):
87                 self.Refresh()
88
89         def OnMouseLeftDown(self,e):
90                 pass
91         def OnMouseMotion(self, e):
92                 pass
93         def OnPaint(self, e):
94                 pass
95
96 class glButton(object):
97         def __init__(self, parent, imageID, tooltip, x, y, callback):
98                 self._tooltip = tooltip
99                 self._parent = parent
100                 self._imageID = imageID
101                 self._x = x
102                 self._y = y
103                 self._callback = callback
104                 self._parent._glGuiControlList.append(self)
105                 self._selected = False
106                 self._focus = False
107                 self._hidden = False
108
109         def setSelected(self, value):
110                 self._selected = value
111
112         def setHidden(self, value):
113                 self._hidden = value
114
115         def getSelected(self):
116                 return self._selected
117
118         def _getSize(self):
119                 return self._parent._buttonSize
120
121         def _getPixelPos(self):
122                 bs = self._getSize()
123                 x = self._x * bs * 1.3 + bs * 0.8
124                 y = self._y * bs * 1.3 + bs * 0.8
125                 if self._x < 0:
126                         x = self._parent.GetSize().GetWidth() + x - bs * 0.2
127                 return x, y
128
129         def draw(self):
130                 if self._hidden:
131                         return
132                 if self._parent._glButtonsTexture is None:
133                         self._parent._glButtonsTexture = opengl.loadGLTexture('glButtons.png')
134
135                 cx = (self._imageID % 4) / 4
136                 cy = int(self._imageID / 4) / 4
137                 bs = self._parent._buttonSize
138                 pos = self._getPixelPos()
139
140                 glPushMatrix()
141                 glTranslatef(pos[0], pos[1], 0)
142                 glBindTexture(GL_TEXTURE_2D, self._parent._glButtonsTexture)
143                 glEnable(GL_TEXTURE_2D)
144                 scale = 0.8
145                 if self._selected:
146                         scale = 1.0
147                 elif self._focus:
148                         scale = 0.9
149                 glScalef(bs * scale, bs * scale, bs * scale)
150                 glColor4ub(255,255,255,255)
151                 glBegin(GL_QUADS)
152                 glTexCoord2f(cx+0.25, cy)
153                 glVertex2f( 0.5,-0.5)
154                 glTexCoord2f(cx, cy)
155                 glVertex2f(-0.5,-0.5)
156                 glTexCoord2f(cx, cy+0.25)
157                 glVertex2f(-0.5, 0.5)
158                 glTexCoord2f(cx+0.25, cy+0.25)
159                 glVertex2f( 0.5, 0.5)
160                 glEnd()
161                 glDisable(GL_TEXTURE_2D)
162                 if self._focus:
163                         glColor4ub(0,0,0,255)
164                         glTranslatef(0, -0.55, 0)
165                         opengl.glDrawStringCenter(self._tooltip)
166                 glPopMatrix()
167
168         def _checkHit(self, x, y):
169                 if self._hidden:
170                         return False
171                 bs = self._getSize()
172                 pos = self._getPixelPos()
173                 return -bs * 0.5 <= x - pos[0] <= bs * 0.5 and -bs * 0.5 <= y - pos[1] <= bs * 0.5
174
175         def OnMouseMotion(self, x, y):
176                 if self._checkHit(x, y):
177                         self._focus = True
178                         return True
179                 self._focus = False
180                 return False
181
182         def OnMouseDown(self, x, y):
183                 if self._checkHit(x, y):
184                         self._callback()
185                         return True
186                 return False