1 from __future__ import absolute_import
2 from __future__ import division
3 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
11 from wx import glcanvas
13 OpenGL.ERROR_CHECKING = False
14 from OpenGL.GL import *
16 from Cura.gui.util import opengl
18 class animation(object):
19 def __init__(self, gui, start, end, runTime):
22 self._startTime = time.time()
23 self._runTime = runTime
24 gui._animationList.append(self)
27 return time.time() > self._startTime + self._runTime
29 def getPosition(self):
32 f = (time.time() - self._startTime) / self._runTime
35 #f = 6*tc*ts + -15*ts*ts + 10*tc
37 return self._start + (self._end - self._start) * f
39 class glGuiControl(object):
40 def __init__(self, parent, pos):
42 self._base = parent._base
44 self._size = (0,0, 1, 1)
45 self._parent.add(self)
47 def setSize(self, x, y, w, h):
48 self._size = (x, y, w, h)
56 def updateLayout(self):
60 for n in xrange(self._parent._glGuiControlList.index(self) + 1, len(self._parent._glGuiControlList)):
61 if self._parent._glGuiControlList[n].setFocus():
63 for n in xrange(0, self._parent._glGuiControlList.index(self)):
64 if self._parent._glGuiControlList[n].setFocus():
67 def focusPrevious(self):
68 for n in xrange(self._parent._glGuiControlList.index(self) -1, -1, -1):
69 if self._parent._glGuiControlList[n].setFocus():
71 for n in xrange(len(self._parent._glGuiControlList) - 1, self._parent._glGuiControlList.index(self), -1):
72 if self._parent._glGuiControlList[n].setFocus():
79 return self._base._focus == self
81 def OnMouseUp(self, x, y):
84 def OnKeyChar(self, key):
87 class glGuiContainer(glGuiControl):
88 def __init__(self, parent, pos):
89 self._glGuiControlList = []
90 glGuiLayoutButtons(self)
91 super(glGuiContainer, self).__init__(parent, pos)
94 self._glGuiControlList.append(ctrl)
97 def OnMouseDown(self, x, y, button):
98 for ctrl in self._glGuiControlList:
99 if ctrl.OnMouseDown(x, y, button):
103 def OnMouseUp(self, x, y):
104 for ctrl in self._glGuiControlList:
105 if ctrl.OnMouseUp(x, y):
109 def OnMouseMotion(self, x, y):
111 for ctrl in self._glGuiControlList:
112 if ctrl.OnMouseMotion(x, y):
117 for ctrl in self._glGuiControlList:
120 def updateLayout(self):
121 self._layout.update()
122 for ctrl in self._glGuiControlList:
125 class glGuiPanel(glcanvas.GLCanvas):
126 def __init__(self, parent):
127 attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 32, glcanvas.WX_GL_STENCIL_SIZE, 8)
128 glcanvas.GLCanvas.__init__(self, parent, style=wx.WANTS_CHARS, attribList = attribList)
131 self._container = None
132 self._container = glGuiContainer(self, (0,0))
133 self._shownError = False
135 self._context = glcanvas.GLContext(self)
136 self._glButtonsTexture = None
137 self._glRobotTexture = None
138 self._buttonSize = 64
140 self._animationList = []
141 self.glReleaseList = []
142 self._refreshQueued = False
144 wx.EVT_PAINT(self, self._OnGuiPaint)
145 wx.EVT_SIZE(self, self._OnSize)
146 wx.EVT_ERASE_BACKGROUND(self, self._OnEraseBackground)
147 wx.EVT_LEFT_DOWN(self, self._OnGuiMouseDown)
148 wx.EVT_LEFT_DCLICK(self, self._OnGuiMouseDown)
149 wx.EVT_LEFT_UP(self, self._OnGuiMouseUp)
150 wx.EVT_RIGHT_DOWN(self, self._OnGuiMouseDown)
151 wx.EVT_RIGHT_DCLICK(self, self._OnGuiMouseDown)
152 wx.EVT_RIGHT_UP(self, self._OnGuiMouseUp)
153 wx.EVT_MIDDLE_DOWN(self, self._OnGuiMouseDown)
154 wx.EVT_MIDDLE_DCLICK(self, self._OnGuiMouseDown)
155 wx.EVT_MIDDLE_UP(self, self._OnGuiMouseUp)
156 wx.EVT_MOTION(self, self._OnGuiMouseMotion)
157 wx.EVT_CHAR(self, self._OnGuiKeyChar)
158 wx.EVT_KILL_FOCUS(self, self.OnFocusLost)
159 wx.EVT_IDLE(self, self._OnIdle)
161 def _OnIdle(self, e):
162 if len(self._animationList) > 0 or self._refreshQueued:
163 self._refreshQueued = False
164 for anim in self._animationList:
166 self._animationList.remove(anim)
169 def _OnGuiKeyChar(self, e):
170 if self._focus is not None:
171 self._focus.OnKeyChar(e.GetKeyCode())
174 self.OnKeyChar(e.GetKeyCode())
176 def OnFocusLost(self, e):
180 def _OnGuiMouseDown(self,e):
182 if self._container.OnMouseDown(e.GetX(), e.GetY(), e.GetButton()):
187 def _OnGuiMouseUp(self, e):
188 if self._container.OnMouseUp(e.GetX(), e.GetY()):
193 def _OnGuiMouseMotion(self,e):
195 if not self._container.OnMouseMotion(e.GetX(), e.GetY()):
196 self.OnMouseMotion(e)
198 def _OnGuiPaint(self, e):
199 h = self.GetSize().GetHeight()
200 w = self.GetSize().GetWidth()
201 oldButtonSize = self._buttonSize
205 self._buttonSize = 32
207 self._buttonSize = 48
209 self._buttonSize = 64
211 self._buttonSize = 80
213 self._buttonSize = 96
214 if self._buttonSize != oldButtonSize:
215 self._container.updateLayout()
217 dc = wx.PaintDC(self)
219 self.SetCurrent(self._context)
220 for obj in self.glReleaseList:
222 del self.glReleaseList[:]
228 errStr = 'An error has occurred during the 3D view drawing.'
229 tb = traceback.extract_tb(sys.exc_info()[2])
230 errStr += "\n%s: '%s'" % (str(sys.exc_info()[0].__name__), str(sys.exc_info()[1]))
231 for n in xrange(len(tb)-1, -1, -1):
233 errStr += "\n @ %s:%s:%d" % (os.path.basename(locationInfo[0]), locationInfo[2], locationInfo[1])
234 if not self._shownError:
235 wx.CallAfter(wx.MessageBox, errStr, '3D window error', wx.OK | wx.ICON_EXCLAMATION)
236 self._shownError = True
239 if self._glButtonsTexture is None:
240 self._glButtonsTexture = opengl.loadGLTexture('glButtons.png')
241 self._glRobotTexture = opengl.loadGLTexture('UltimakerRobot.png')
243 glDisable(GL_DEPTH_TEST)
245 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
246 glDisable(GL_LIGHTING)
247 glColor4ub(255,255,255,255)
249 glMatrixMode(GL_PROJECTION)
251 size = self.GetSize()
252 glOrtho(0, size.GetWidth()-1, size.GetHeight()-1, 0, -1000.0, 1000.0)
253 glMatrixMode(GL_MODELVIEW)
256 self._container.draw()
258 glBindTexture(GL_TEXTURE_2D, self._glRobotTexture)
259 glEnable(GL_TEXTURE_2D)
262 glTranslate(size.GetWidth() - 8,size.GetHeight() - 32,0)
263 s = self._buttonSize * 1.4
275 glDisable(GL_TEXTURE_2D)
278 def _OnEraseBackground(self,event):
279 #Workaround for windows background redraw flicker.
283 self._container.setSize(0, 0, self.GetSize().GetWidth(), self.GetSize().GetHeight())
284 self._container.updateLayout()
287 def OnMouseDown(self,e):
289 def OnMouseUp(self,e):
291 def OnMouseMotion(self, e):
293 def OnKeyChar(self, keyCode):
295 def OnPaint(self, e):
297 def OnKeyChar(self, keycode):
300 def QueueRefresh(self):
301 wx.CallAfter(self._queueRefresh)
303 def _queueRefresh(self):
304 self._refreshQueued = True
307 if self._container is not None:
308 self._container.add(ctrl)
310 class glGuiLayoutButtons(object):
311 def __init__(self, parent):
312 self._parent = parent
313 self._parent._layout = self
316 bs = self._parent._base._buttonSize
317 x0, y0, w, h = self._parent.getSize()
319 for ctrl in self._parent._glGuiControlList:
322 x = w + pos[0] * gridSize - bs * 0.2
324 x = pos[0] * gridSize + bs * 0.2
326 y = h + pos[1] * gridSize * 1.2 - bs * 0.2
328 y = pos[1] * gridSize * 1.2 + bs * 0.2
329 ctrl.setSize(x, y, gridSize, gridSize)
331 def getLayoutSize(self):
332 _, _, w, h = self._parent.getSize()
335 class glGuiLayoutGrid(object):
336 def __init__(self, parent):
337 self._parent = parent
338 self._parent._layout = self
340 self._alignBottom = True
343 borderSize = self._parent._base._buttonSize * 0.2
344 x0, y0, w, h = self._parent.getSize()
349 for ctrl in self._parent._glGuiControlList:
351 w, h = ctrl.getMinSize()
355 widths[x] = max(widths[x], w)
359 heights[y] = max(heights[y], h)
360 self._size = sum(widths.values()) + borderSize * 2, sum(heights.values()) + borderSize * 2
361 if self._alignBottom:
362 y0 -= self._size[1] - self._parent.getSize()[3]
363 self._parent.setSize(x0 - borderSize, y0 - borderSize, self._size[0], self._size[1])
364 for ctrl in self._parent._glGuiControlList:
368 for n in xrange(0, x):
372 for n in xrange(0, y):
376 ctrl.setSize(x1, y1, widths[x], heights[y])
378 def getLayoutSize(self):
381 class glButton(glGuiControl):
382 def __init__(self, parent, imageID, tooltip, pos, callback, size = None):
383 self._buttonSize = size
385 super(glButton, self).__init__(parent, pos)
386 self._tooltip = tooltip
387 self._parent = parent
388 self._imageID = imageID
389 self._callback = callback
390 self._selected = False
392 self._disabled = False
393 self._showExpandArrow = False
394 self._progressBar = None
395 self._altTooltip = ''
397 def setSelected(self, value):
398 self._selected = value
400 def setExpandArrow(self, value):
401 self._showExpandArrow = value
403 def setHidden(self, value):
406 def setDisabled(self, value):
407 self._disabled = value
409 def setProgressBar(self, value):
410 self._progressBar = value
412 def getProgressBar(self):
413 return self._progressBar
415 def setBottomText(self, value):
416 self._altTooltip = value
418 def getSelected(self):
419 return self._selected
421 def getMinSize(self):
424 if self._buttonSize is not None:
425 return self._buttonSize, self._buttonSize
426 return self._base._buttonSize, self._base._buttonSize
428 def _getPixelPos(self):
429 x0, y0, w, h = self.getSize()
430 return x0 + w / 2, y0 + h / 2
436 cx = (self._imageID % 4) / 4
437 cy = int(self._imageID / 4) / 4
438 bs = self.getMinSize()[0]
439 pos = self._getPixelPos()
441 glBindTexture(GL_TEXTURE_2D, self._base._glButtonsTexture)
448 glColor4ub(128,128,128,128)
450 glColor4ub(255,255,255,255)
451 opengl.glDrawTexturedQuad(pos[0]-bs*scale/2, pos[1]-bs*scale/2, bs*scale, bs*scale, 0)
452 opengl.glDrawTexturedQuad(pos[0]-bs*scale/2, pos[1]-bs*scale/2, bs*scale, bs*scale, self._imageID)
453 if self._showExpandArrow:
455 opengl.glDrawTexturedQuad(pos[0]+bs*scale/2-bs*scale/4*1.2, pos[1]-bs*scale/2*1.2, bs*scale/4, bs*scale/4, 1)
457 opengl.glDrawTexturedQuad(pos[0]+bs*scale/2-bs*scale/4*1.2, pos[1]-bs*scale/2*1.2, bs*scale/4, bs*scale/4, 1, 2)
459 glTranslatef(pos[0], pos[1], 0)
460 glDisable(GL_TEXTURE_2D)
462 glTranslatef(0, -0.55*bs*scale, 0)
465 glColor4ub(60,60,60,255)
466 glTranslatef(-1, -1, 0)
467 opengl.glDrawStringCenter(self._tooltip)
468 glTranslatef(0, 2, 0)
469 opengl.glDrawStringCenter(self._tooltip)
470 glTranslatef(2, 0, 0)
471 opengl.glDrawStringCenter(self._tooltip)
472 glTranslatef(0, -2, 0)
473 opengl.glDrawStringCenter(self._tooltip)
476 glColor4ub(255,255,255,255)
477 opengl.glDrawStringCenter(self._tooltip)
479 progress = self._progressBar
480 if progress is not None:
481 glColor4ub(60,60,60,255)
482 opengl.glDrawQuad(pos[0]-bs/2, pos[1]+bs/2, bs, bs / 4)
483 glColor4ub(255,255,255,255)
484 opengl.glDrawQuad(pos[0]-bs/2+2, pos[1]+bs/2+2, (bs - 5) * progress + 1, bs / 4 - 4)
485 elif len(self._altTooltip) > 0:
487 glTranslatef(pos[0], pos[1], 0)
488 glTranslatef(0.6*bs*scale, 0, 0)
491 glColor4ub(60,60,60,255)
492 glTranslatef(-1, -1, 0)
493 opengl.glDrawStringLeft(self._altTooltip)
494 glTranslatef(0, 2, 0)
495 opengl.glDrawStringLeft(self._altTooltip)
496 glTranslatef(2, 0, 0)
497 opengl.glDrawStringLeft(self._altTooltip)
498 glTranslatef(0, -2, 0)
499 opengl.glDrawStringLeft(self._altTooltip)
502 glColor4ub(255,255,255,255)
503 opengl.glDrawStringLeft(self._altTooltip)
506 def _checkHit(self, x, y):
507 if self._hidden or self._disabled:
509 bs = self.getMinSize()[0]
510 pos = self._getPixelPos()
511 return -bs * 0.5 <= x - pos[0] <= bs * 0.5 and -bs * 0.5 <= y - pos[1] <= bs * 0.5
513 def OnMouseMotion(self, x, y):
514 if self._checkHit(x, y):
520 def OnMouseDown(self, x, y, button):
521 if self._checkHit(x, y):
522 self._callback(button)
526 class glRadioButton(glButton):
527 def __init__(self, parent, imageID, tooltip, pos, group, callback):
528 super(glRadioButton, self).__init__(parent, imageID, tooltip, pos, self._onRadioSelect)
530 self._radioCallback = callback
531 self._group.append(self)
533 def setSelected(self, value):
534 self._selected = value
536 def _onRadioSelect(self, button):
537 self._base._focus = None
538 for ctrl in self._group:
540 ctrl.setSelected(False)
541 if self.getSelected():
542 self.setSelected(False)
544 self.setSelected(True)
545 self._radioCallback(button)
547 class glComboButton(glButton):
548 def __init__(self, parent, tooltip, imageIDs, tooltips, pos, callback):
549 super(glComboButton, self).__init__(parent, imageIDs[0], tooltip, pos, self._onComboOpenSelect)
550 self._imageIDs = imageIDs
551 self._tooltips = tooltips
552 self._comboCallback = callback
555 def _onComboOpenSelect(self, button):
557 self._base._focus = None
559 self._base._focus = self
564 self._selected = self.hasFocus()
565 super(glComboButton, self).draw()
567 bs = self._base._buttonSize / 2
568 pos = self._getPixelPos()
570 if not self._selected:
574 glTranslatef(pos[0]+bs*0.5, pos[1] + bs*0.5, 0)
575 glBindTexture(GL_TEXTURE_2D, self._base._glButtonsTexture)
576 for n in xrange(0, len(self._imageIDs)):
577 glTranslatef(0, bs, 0)
578 glColor4ub(255,255,255,255)
579 opengl.glDrawTexturedQuad(-0.5*bs,-0.5*bs,bs,bs, 0)
580 opengl.glDrawTexturedQuad(-0.5*bs,-0.5*bs,bs,bs, self._imageIDs[n])
581 glDisable(GL_TEXTURE_2D)
584 glTranslatef(-0.55*bs, 0.1*bs, 0)
587 glColor4ub(60,60,60,255)
588 glTranslatef(-1, -1, 0)
589 opengl.glDrawStringRight(self._tooltips[n])
590 glTranslatef(0, 2, 0)
591 opengl.glDrawStringRight(self._tooltips[n])
592 glTranslatef(2, 0, 0)
593 opengl.glDrawStringRight(self._tooltips[n])
594 glTranslatef(0, -2, 0)
595 opengl.glDrawStringRight(self._tooltips[n])
598 glColor4ub(255,255,255,255)
599 opengl.glDrawStringRight(self._tooltips[n])
604 return self._selection
606 def setValue(self, value):
607 self._selection = value
608 self._imageID = self._imageIDs[self._selection]
609 self._comboCallback()
611 def OnMouseDown(self, x, y, button):
612 if self._hidden or self._disabled:
615 bs = self._base._buttonSize / 2
616 pos = self._getPixelPos()
617 if 0 <= x - pos[0] <= bs and 0 <= y - pos[1] - bs <= bs * len(self._imageIDs):
618 self._selection = int((y - pos[1] - bs) / bs)
619 self._imageID = self._imageIDs[self._selection]
620 self._base._focus = None
621 self._comboCallback()
623 return super(glComboButton, self).OnMouseDown(x, y, button)
625 class glFrame(glGuiContainer):
626 def __init__(self, parent, pos):
627 super(glFrame, self).__init__(parent, pos)
628 self._selected = False
632 def setSelected(self, value):
633 self._selected = value
635 def setHidden(self, value):
637 for child in self._glGuiControlList:
638 if self._base._focus == child:
639 self._base._focus = None
641 def getSelected(self):
642 return self._selected
644 def getMinSize(self):
645 return self._base._buttonSize, self._base._buttonSize
647 def _getPixelPos(self):
648 x0, y0, w, h = self.getSize()
655 bs = self._parent._buttonSize
656 pos = self._getPixelPos()
658 size = self._layout.getLayoutSize()
659 glColor4ub(255,255,255,255)
660 opengl.glDrawStretchedQuad(pos[0], pos[1], size[0], size[1], bs*0.75, 0)
661 #Draw the controls on the frame
662 super(glFrame, self).draw()
664 def _checkHit(self, x, y):
667 pos = self._getPixelPos()
668 w, h = self._layout.getLayoutSize()
669 return 0 <= x - pos[0] <= w and 0 <= y - pos[1] <= h
671 def OnMouseMotion(self, x, y):
672 super(glFrame, self).OnMouseMotion(x, y)
673 if self._checkHit(x, y):
679 def OnMouseDown(self, x, y, button):
680 if self._checkHit(x, y):
681 super(glFrame, self).OnMouseDown(x, y, button)
685 class glNotification(glFrame):
686 def __init__(self, parent, pos):
688 super(glNotification, self).__init__(parent, pos)
689 glGuiLayoutGrid(self)._alignBottom = False
690 self._label = glLabel(self, "Notification", (0, 0))
691 self._buttonEject = glButton(self, 31, "Eject", (1, 0), self.onEject, 25)
692 self._button = glButton(self, 30, "", (2, 0), self.onClose, 25)
693 self._padding = glLabel(self, "", (0, 1))
696 def setSize(self, x, y, w, h):
697 w, h = self._layout.getLayoutSize()
698 baseSize = self._base.GetSizeTuple()
699 if self._anim is not None:
700 super(glNotification, self).setSize(baseSize[0] / 2 - w / 2, baseSize[1] - self._anim.getPosition() - self._base._buttonSize * 0.2, 1, 1)
702 super(glNotification, self).setSize(baseSize[0] / 2 - w / 2, baseSize[1] - self._base._buttonSize * 0.2, 1, 1)
705 self.setSize(0,0,0,0)
707 super(glNotification, self).draw()
709 def message(self, text, ejectCallback = None):
710 self._anim = animation(self._base, -20, 25, 1)
711 self.setHidden(False)
712 self._label.setLabel(text)
713 self._buttonEject.setHidden(ejectCallback is None)
714 self._ejectCallback = ejectCallback
715 self._base._queueRefresh()
718 def onEject(self, button):
720 self._ejectCallback()
722 def onClose(self, button):
723 if self._anim is not None:
724 self._anim = animation(self._base, self._anim.getPosition(), -20, 1)
726 self._anim = animation(self._base, 25, -20, 1)
728 class glLabel(glGuiControl):
729 def __init__(self, parent, label, pos):
731 super(glLabel, self).__init__(parent, pos)
733 def setLabel(self, label):
736 def getMinSize(self):
737 w, h = opengl.glGetStringSize(self._label)
740 def _getPixelPos(self):
741 x0, y0, w, h = self.getSize()
745 x, y, w, h = self.getSize()
748 glTranslatef(x, y, 0)
750 # glColor4ub(255,255,255,128)
762 glTranslate(5, h - 5, 0)
763 glColor4ub(255,255,255,255)
764 opengl.glDrawStringLeft(self._label)
767 def _checkHit(self, x, y):
770 def OnMouseMotion(self, x, y):
773 def OnMouseDown(self, x, y, button):
776 class glNumberCtrl(glGuiControl):
777 def __init__(self, parent, value, pos, callback):
778 self._callback = callback
779 self._value = str(value)
782 self._inCallback = False
783 super(glNumberCtrl, self).__init__(parent, pos)
785 def setValue(self, value):
788 self._value = str(value)
790 def getMinSize(self):
791 w, h = opengl.glGetStringSize("VALUES")
794 def _getPixelPos(self):
795 x0, y0, w, h = self.getSize()
799 x, y, w, h = self.getSize()
802 glTranslatef(x, y, 0)
805 glColor4ub(255,255,255,255)
807 glColor4ub(255,255,255,192)
819 glTranslate(5, h - 5, 0)
820 glColor4ub(0,0,0,255)
821 opengl.glDrawStringLeft(self._value)
823 glTranslate(opengl.glGetStringSize(self._value[0:self._selectPos])[0] - 2, -1, 0)
824 opengl.glDrawStringLeft('|')
827 def _checkHit(self, x, y):
828 x1, y1, w, h = self.getSize()
829 return 0 <= x - x1 <= w and 0 <= y - y1 <= h
831 def OnMouseMotion(self, x, y):
834 def OnMouseDown(self, x, y, button):
835 if self._checkHit(x, y):
840 def OnKeyChar(self, c):
841 self._inCallback = True
844 self._selectPos = max(0, self._selectPos)
845 if c == wx.WXK_RIGHT:
847 self._selectPos = min(self._selectPos, len(self._value))
850 value = float(self._value)
855 self._value = str(value)
856 self._callback(self._value)
859 value = float(self._value)
865 self._value = str(value)
866 self._callback(self._value)
867 if c == wx.WXK_BACK and self._selectPos > 0:
868 self._value = self._value[0:self._selectPos - 1] + self._value[self._selectPos:]
870 self._callback(self._value)
871 if c == wx.WXK_DELETE:
872 self._value = self._value[0:self._selectPos] + self._value[self._selectPos + 1:]
873 self._callback(self._value)
874 if c == wx.WXK_TAB or c == wx.WXK_NUMPAD_ENTER or c == wx.WXK_RETURN:
875 if wx.GetKeyState(wx.WXK_SHIFT):
879 if (ord('0') <= c <= ord('9') or c == ord('.')) and len(self._value) < self._maxLen:
880 self._value = self._value[0:self._selectPos] + chr(c) + self._value[self._selectPos:]
882 self._callback(self._value)
883 self._inCallback = False
886 self._base._focus = self
887 self._selectPos = len(self._value)
890 class glCheckbox(glGuiControl):
891 def __init__(self, parent, value, pos, callback):
892 self._callback = callback
896 self._inCallback = False
897 super(glCheckbox, self).__init__(parent, pos)
899 def setValue(self, value):
902 self._value = str(value)
907 def getMinSize(self):
910 def _getPixelPos(self):
911 x0, y0, w, h = self.getSize()
915 x, y, w, h = self.getSize()
918 glTranslatef(x, y, 0)
920 glColor3ub(255,255,255)
922 opengl.glDrawTexturedQuad(w/2-h/2,0, h, h, 28)
924 opengl.glDrawTexturedQuad(w/2-h/2,0, h, h, 29)
928 def _checkHit(self, x, y):
929 x1, y1, w, h = self.getSize()
930 return 0 <= x - x1 <= w and 0 <= y - y1 <= h
932 def OnMouseMotion(self, x, y):
935 def OnMouseDown(self, x, y, button):
936 if self._checkHit(x, y):
937 self._value = not self._value
941 class glSlider(glGuiControl):
942 def __init__(self, parent, value, minValue, maxValue, pos, callback):
943 super(glSlider, self).__init__(parent, pos)
944 self._callback = callback
948 self._minValue = minValue
949 self._maxValue = maxValue
951 def setValue(self, value):
953 self._value = max(self._minValue, self._value)
954 self._value = min(self._maxValue, self._value)
959 def setRange(self, minValue, maxValue):
960 if maxValue < minValue:
962 self._minValue = minValue
963 self._maxValue = maxValue
964 self._value = max(minValue, self._value)
965 self._value = min(maxValue, self._value)
967 def getMinValue(self):
968 return self._minValue
970 def getMaxValue(self):
971 return self._maxValue
973 def setHidden(self, value):
976 def getMinSize(self):
977 return self._base._buttonSize * 0.2, self._base._buttonSize * 4
979 def _getPixelPos(self):
980 x0, y0, w, h = self.getSize()
981 minSize = self.getMinSize()
982 return x0 + w / 2 - minSize[0] / 2, y0 + h / 2 - minSize[1] / 2
988 w, h = self.getMinSize()
989 pos = self._getPixelPos()
992 glTranslatef(pos[0], pos[1], 0)
993 glDisable(GL_TEXTURE_2D)
995 glColor4ub(60,60,60,255)
997 glColor4ub(60,60,60,192)
999 glVertex2f( w/2,-h/2)
1000 glVertex2f(-w/2,-h/2)
1001 glVertex2f(-w/2, h/2)
1002 glVertex2f( w/2, h/2)
1004 scrollLength = h - w
1005 glTranslate(0.0,scrollLength/2,0)
1007 glColor4ub(0,0,0,255)
1009 glTranslate(-w/2,opengl.glGetStringSize(str(self._minValue))[1]/2,0)
1010 opengl.glDrawStringRight(str(self._minValue))
1011 glTranslate(0,-scrollLength,0)
1012 opengl.glDrawStringRight(str(self._maxValue))
1013 if self._maxValue-self._minValue > 0:
1014 glTranslate(w,scrollLength-scrollLength*((self._value-self._minValue)/(self._maxValue-self._minValue)),0)
1015 opengl.glDrawStringLeft(str(self._value))
1017 glColor4ub(255,255,255,240)
1018 if self._maxValue - self._minValue != 0:
1019 glTranslate(0.0,-scrollLength*((self._value-self._minValue)/(self._maxValue-self._minValue)),0)
1021 glVertex2f( w/2,-w/2)
1022 glVertex2f(-w/2,-w/2)
1023 glVertex2f(-w/2, w/2)
1024 glVertex2f( w/2, w/2)
1028 def _checkHit(self, x, y):
1031 pos = self._getPixelPos()
1032 w, h = self.getMinSize()
1033 return -w/2 <= x - pos[0] <= w/2 and -h/2 <= y - pos[1] <= h/2
1036 self._base._focus = self
1039 def OnMouseMotion(self, x, y):
1041 w, h = self.getMinSize()
1042 scrollLength = h - w
1043 pos = self._getPixelPos()
1044 self.setValue(int(self._minValue + (self._maxValue - self._minValue) * -(y - pos[1] - scrollLength/2) / scrollLength))
1047 if self._checkHit(x, y):
1053 def OnMouseDown(self, x, y, button):
1054 if self._checkHit(x, y):
1056 self.OnMouseMotion(x, y)
1060 def OnMouseUp(self, x, y):
1062 self._base._focus = None