forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDirectEntryScroll.py
More file actions
139 lines (113 loc) · 4.68 KB
/
DirectEntryScroll.py
File metadata and controls
139 lines (113 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
__all__ = ['DirectEntryScroll']
from panda3d.core import *
from . import DirectGuiGlobals as DGG
from .DirectScrolledFrame import *
from .DirectFrame import *
from .DirectEntry import *
class DirectEntryScroll(DirectFrame):
def __init__(self, entry, parent = None, **kw):
optiondefs = (
('pgFunc', PGVirtualFrame, None),
('relief', None, None),
('clipSize', (-1, 1, -1, 1), self.setClipSize),
)
self.defineoptions(kw, optiondefs)
DirectFrame.__init__(self, parent, **kw)
self.canvas = None
self.visXMin = 0.0
self.visXMax = 0.0
self.clipXMin = 0.0
self.clipXMax = 0.0
self.initialiseoptions(DirectEntryScroll)
# don't set a scale on the entry
# instead make it the correct size, use something like:
# text_scale = 0.035,
# frameSize = (-0.006, 3.2, -0.015, 0.036),
# if you need to scale the entry scale it's parent instead
self.canvas = NodePath(self.guiItem.getCanvasNode())
self.canvas.setPos(0,0,0)
self.entry = None
if entry is not None:
self.entry = entry
self.entry.reparentTo(self.canvas)
self.entry.bind(DGG.CURSORMOVE, self.cursorMove)
self.canvas.node().setBounds(OmniBoundingVolume())
self.canvas.node().setFinal(1)
self.resetCanvas()
def setEntry(self, entry):
"""
Sets a DirectEntry element for this scroll frame. A DirectEntryScroll
can only hold one entry at a time, so make sure to not call this
function twice or call clearEntry before to make sure no entry
is already set.
"""
assert self.entry is None, "An entry was already set for this DirectEntryScroll element"
self.entry = entry
self.entry.reparentTo(self.canvas)
self.entry.bind(DGG.CURSORMOVE, self.cursorMove)
def clearEntry(self):
"""
detaches and unbinds the entry from the scroll frame and its
events. You'll be responsible for destroying it.
"""
if self.entry is None: return
self.entry.unbind(DGG.CURSORMOVE)
self.entry.detachNode()
self.entry = None
def cursorMove(self, cursorX, cursorY):
cursorX = self.entry.guiItem.getCursorX() * self.entry['text_scale'][0]
canvasX = self.canvas.getX()
visXMin = self.clipXMin - canvasX
visXMax = self.clipXMax - canvasX
visXCenter = (visXMin + visXMax) * 0.5
distanceToCenter = visXCenter - cursorX
clipExtent = self.clipXMax - self.clipXMin
entryExtent = self.entry['text_scale'][0] * self.entry['width']
entryWiggle = entryExtent - clipExtent
if abs(distanceToCenter) > (clipExtent * 0.5):
self.moveToCenterCursor()
def moveToCenterCursor(self):
cursorX = self.entry.guiItem.getCursorX() * self.entry['text_scale'][0]
canvasX = self.canvas.getX()
visXMin = self.clipXMin - canvasX
visXMax = self.clipXMax - canvasX
visXCenter = (visXMin + visXMax) * 0.5
distanceToCenter = visXCenter - cursorX
newX = canvasX + distanceToCenter
clipExtent = self.clipXMax - self.clipXMin
entryExtent = self.entry['text_scale'][0] * self.entry['width']
entryWiggle = entryExtent - clipExtent
if self.entry.guiItem.getCursorPosition() <= 0: #deals with the cursor jump bug
newX = 0.0
elif newX > 0.0:
newX = 0.0
elif newX < (-entryWiggle):
newX = -entryWiggle
#print("CursorX %s CanvasX %s VisCenter %s Distance %s NewX %s Wiggle %s" % (cursorX, canvasX, visXCenter, distanceToCenter, newX, entryWiggle))
self.canvas.setX(newX)
def destroy(self):
# Destroy children of the canvas
for child in self.canvas.getChildren():
childGui = self.guiDict.get(child.getName())
if childGui:
childGui.destroy()
else:
parts = child.getName().split('-')
simpleChildGui = self.guiDict.get(parts[-1])
if simpleChildGui:
simpleChildGui.destroy()
self.entry.destroy()
self.entry = None
DirectFrame.destroy(self)
def getCanvas(self):
return self.canvas
def setClipSize(self):
self.guiItem.setClipFrame(self['clipSize'])
self.clipXMin = self['clipSize'][0]
self.clipXMax = self['clipSize'][1]
self.visXMin = self.clipXMin
self.visXMax = self.clipXMax
if self.canvas:
self.resetCanvas()
def resetCanvas(self):
self.canvas.setPos(0,0,0)