LUIFrame.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from __future__ import print_function
  2. from LUIObject import LUIObject
  3. from LUISprite import LUISprite
  4. from LUILayouts import LUICornerLayout
  5. from LUIInitialState import LUIInitialState
  6. from LUIScrollableRegion import LUIScrollableRegion
  7. from panda3d.core import Vec2
  8. __all__ = ["LUIFrame"]
  9. class LUIFrame(LUIObject):
  10. """ A container which can store multiple ui-elements. If you don't want a
  11. border/background, you should use an empty LUIObject as container instead.
  12. """
  13. FS_sunken = 1
  14. FS_raised = 2
  15. def __init__(self, inner_padding=5, scrollable=False, style=FS_raised,
  16. **kwargs):
  17. """ Creates a new frame with the given options and style. If scrollable
  18. is True, the contents of the frame will scroll if they don't fit into
  19. the frame height. inner_padding only has effect if scrollable is True.
  20. You can call fit_to_children() to make the frame fit automatically to
  21. it's contents."""
  22. LUIObject.__init__(self)
  23. # Each *style* has a different border size (size of the shadow). The
  24. # border size shouldn't get calculated to the actual framesize, so we
  25. # are determining it first and then substracting it.
  26. # TODO: We could do this automatically, determined by the sprite size
  27. # probably?
  28. self._border_size = 0
  29. self.padding = 10
  30. self.solid = True
  31. prefix = ""
  32. if style == LUIFrame.FS_raised:
  33. temp = LUISprite(self, "Frame_Left", "skin")
  34. self._border_size = temp.width
  35. self.remove_child(temp)
  36. prefix = "Frame_"
  37. elif style == LUIFrame.FS_sunken:
  38. self._border_size = 0
  39. prefix = "SunkenFrame_"
  40. else:
  41. raise Exception("Unkown LUIFrame style: " + style)
  42. LUIInitialState.init(self, kwargs)
  43. self._scrollable = scrollable
  44. self._layout = LUICornerLayout(parent=self, image_prefix=prefix)
  45. self._layout.margin = -(self.padding.top + self._border_size)
  46. if self._scrollable:
  47. self._content = LUIObject(self)
  48. self._content.size = Vec2(self.width, self.height)
  49. self._content.pos = (self._border_size, self._border_size)
  50. self._scroll_content = LUIScrollableRegion(
  51. self._content,
  52. width=self.width - 2 * self.padding.left,
  53. height=self.height - 2 * self.padding.left,
  54. padding=inner_padding)
  55. self.content_node = self._scroll_content.content_node
  56. def hasMouse(self):
  57. if not self.visible: return False
  58. if base.mouseWatcherNode.hasMouse():
  59. mpos = base.mouseWatcherNode.getMouse()
  60. mousePos = (mpos.getX() * base.getAspectRatio(), mpos.getY())
  61. screenWidth = base.win.getProperties().getXSize()
  62. screenHeight = base.win.getProperties().getYSize()
  63. ratio = base.getAspectRatio()
  64. relLeft = -ratio
  65. relTop = 1
  66. zeroXPx = screenWidth / 2
  67. zeroZPx = screenHeight / 2
  68. objWidth = self.get_width()
  69. objHeight = self.get_height()
  70. objX, objZ = [0,0]
  71. if self.center_horizontal:
  72. objX = zeroXPx - (objWidth / 2)
  73. else:
  74. objX = self.pos[0]
  75. objX += self.margin.left
  76. if self.center_vertical:
  77. objZ = zeroZPx - (objHeight / 2)
  78. else:
  79. objZ = self.pos[1]
  80. objZ += self.margin.top
  81. oneUnitPerPixelX = ratio / zeroXPx
  82. oneUnitPerPixelZ = 1 / zeroZPx
  83. left = relLeft + (oneUnitPerPixelX * objX)
  84. top = relTop - (oneUnitPerPixelZ * objZ)
  85. right = left + (oneUnitPerPixelX * objWidth)
  86. bottom = top - (oneUnitPerPixelZ * objHeight)
  87. if (mousePos[0] <= right # Right
  88. and mousePos[0] >= left # Left
  89. and mousePos[1] >= bottom # Bottom
  90. and mousePos[1] <= top): # Top
  91. return True
  92. return False
  93. return False