Work on buttons
@@ -150,3 +150,4 @@ cython_debug/
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
.vscode/
|
||||
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
@@ -47,6 +47,9 @@ def addTab(i):
|
||||
global tabIndex
|
||||
return tabIndex == i
|
||||
|
||||
def getIsVisible():
|
||||
return True
|
||||
|
||||
def onClick(pos):
|
||||
global tabIndex
|
||||
tabIndex = i
|
||||
@@ -54,7 +57,7 @@ def addTab(i):
|
||||
render.renderElements(pos)
|
||||
pg.display.update()
|
||||
|
||||
render.addButton(rect, tabs[i].name, getIsSelected, onClick)
|
||||
render.addButton(rect, tabs[i].name, getIsSelected, getIsVisible, onClick)
|
||||
|
||||
for i in range(len(tabs)):
|
||||
addTab(i)
|
||||
@@ -97,6 +100,10 @@ while running:
|
||||
|
||||
elif event.type == pg.KEYDOWN:
|
||||
tabs[tabIndex].keyDown(event.key)
|
||||
if event.key == pg.K_TAB:
|
||||
tabIndex = (tabIndex + 1) % len(tabs)
|
||||
tabs[tabIndex].load()
|
||||
render.renderElements(pg.mouse.get_pos())
|
||||
|
||||
elif event.type == pg.QUIT:
|
||||
running = False
|
||||
|
||||
@@ -20,15 +20,31 @@ ogDragFramePos = -1
|
||||
|
||||
selFrame = -1
|
||||
|
||||
buttonImages = {}
|
||||
buttonMode = False
|
||||
|
||||
buttonPositions = {
|
||||
'A': ((1089,494),100),
|
||||
'B': ((1187,404),100),
|
||||
'X': ((996,411),100),
|
||||
'Y': ((1093,321),100),
|
||||
|
||||
def getPosKeyframes():
|
||||
frames = []
|
||||
for keyFrame in keyFrames:
|
||||
if keyFrame['type'] == 'position':
|
||||
frames.append(keyFrame)
|
||||
return frames
|
||||
'Dpad': ((549,619),220),
|
||||
|
||||
'Menu': ((832,411),100),
|
||||
'Windows': ((629,411),100),
|
||||
|
||||
'Left_Stick': ((375,422),150),
|
||||
'Right_Stick': ((914,622),150),
|
||||
|
||||
'LB': ((352,184),150),
|
||||
'RB': ((1100,184),150),
|
||||
|
||||
'LT': ((356,67),150),
|
||||
'RT': ((1096,67),150)
|
||||
}
|
||||
|
||||
controllerCount = 2
|
||||
|
||||
|
||||
def getKeyframeAtPos(index):
|
||||
@@ -39,6 +55,13 @@ def getKeyframeAtPos(index):
|
||||
|
||||
|
||||
|
||||
def getFrameIndex(frame):
|
||||
if frame == None:
|
||||
return -1
|
||||
return keyFrames.index(frame)
|
||||
|
||||
|
||||
|
||||
def getPosKeyframeAtPos(index):
|
||||
for frame in keyFrames:
|
||||
if frame["timeIndex"] == index and frame['type'] == 'position':
|
||||
@@ -47,6 +70,15 @@ def getPosKeyframeAtPos(index):
|
||||
|
||||
|
||||
|
||||
def getPosKeyframes():
|
||||
frames = []
|
||||
for keyFrame in keyFrames:
|
||||
if keyFrame['type'] == 'position':
|
||||
frames.append(keyFrame)
|
||||
return frames
|
||||
|
||||
|
||||
|
||||
def getBezierPointCounts():
|
||||
counts = []
|
||||
frames = getPosKeyframes()
|
||||
@@ -64,13 +96,6 @@ def getPosKeyframeByIndex(index):
|
||||
|
||||
|
||||
|
||||
def getFrameIndex(frame):
|
||||
if frame == None:
|
||||
return -1
|
||||
return keyFrames.index(frame)
|
||||
|
||||
|
||||
|
||||
def getSurroundingPosFrames(index):
|
||||
prevFrame = None
|
||||
for i in range(index,-1,-1):
|
||||
@@ -214,6 +239,82 @@ def clickBar(pos, doubleClick):
|
||||
})
|
||||
return
|
||||
|
||||
# def getControllerRects():
|
||||
# rects = []
|
||||
# for i in range(controllerCount):
|
||||
# rects.append()
|
||||
|
||||
def renderXboxControllers():
|
||||
for rect in controllerRects:
|
||||
|
||||
offsetSize = rect[2]/buttonImages['Controller'].get_width()
|
||||
|
||||
def offsetControllerButton(index):
|
||||
pos, size = buttonPositions[index]
|
||||
rect2 = ((pos[0]-(size/2), pos[1]-(size/2), size, size))
|
||||
return (rect[0]+(rect2[0])*offsetSize,rect[1]+(rect2[1])*offsetSize,rect2[2]*offsetSize,rect2[2]*offsetSize)
|
||||
|
||||
|
||||
render.image(buttonImages['Controller'], rect)
|
||||
|
||||
render.image(buttonImages['A'], offsetControllerButton('A'))
|
||||
render.image(buttonImages['B'], offsetControllerButton('B'))
|
||||
render.image(buttonImages['X'], offsetControllerButton('X'))
|
||||
render.image(buttonImages['Y'], offsetControllerButton('Y'))
|
||||
|
||||
render.image(buttonImages['Dpad'], offsetControllerButton('Dpad'))
|
||||
|
||||
render.image(buttonImages['Menu'], offsetControllerButton('Menu'))
|
||||
render.image(buttonImages['Windows'], offsetControllerButton("Windows"))
|
||||
|
||||
render.image(buttonImages['Left_Stick'], offsetControllerButton('Left_Stick'))
|
||||
render.image(buttonImages['Right_Stick'], offsetControllerButton('Right_Stick'))
|
||||
|
||||
|
||||
render.image(buttonImages['LB'], offsetControllerButton('LB'))
|
||||
render.image(buttonImages['RB'], offsetControllerButton('RB'))
|
||||
|
||||
render.image(buttonImages['LT'], offsetControllerButton("LT"))
|
||||
render.image(buttonImages['RT'], offsetControllerButton('RT'))
|
||||
|
||||
def controllerClick(pos):
|
||||
for rect in controllerRects:
|
||||
|
||||
offsetSize = rect[2]/buttonImages['Controller'].get_width()
|
||||
|
||||
def offsetControllerButton(index):
|
||||
pos, size = buttonPositions[index]
|
||||
rect2 = ((pos[0]-(size/2), pos[1]-(size/2), size, size))
|
||||
return (rect[0]+(rect2[0])*offsetSize,rect[1]+(rect2[1])*offsetSize,rect2[2]*offsetSize,rect2[2]*offsetSize)
|
||||
|
||||
|
||||
if render.isInRect(pos, offsetControllerButton('A')):
|
||||
print('A!')
|
||||
elif render.isInRect(pos, offsetControllerButton('B')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('X')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('Y')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('Dpad')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('Menu')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('Windows')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('Left_Stick')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('Right_Stick')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('LB')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('RB')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('LT')):
|
||||
pass
|
||||
elif render.isInRect(pos, offsetControllerButton('RT')):
|
||||
pass
|
||||
|
||||
class buttonEditor:
|
||||
name = "Button Editor"
|
||||
|
||||
@@ -229,23 +330,64 @@ class buttonEditor:
|
||||
global bottomBarRect
|
||||
bottomBarRect = (0, (render.screen.get_height()-render.bottomBarHeight), render.screen.get_width(), render.bottomBarHeight)
|
||||
|
||||
global buttonImages
|
||||
buttonImages = {
|
||||
"Controller": render.pg.image.load('images/XboxOne_Diagram_Simple.png').convert_alpha(),
|
||||
|
||||
"A": render.pg.image.load('images/XboxOne_A.png').convert_alpha(),
|
||||
"B": render.pg.image.load('images/XboxOne_B.png').convert_alpha(),
|
||||
"X": render.pg.image.load('images/XboxOne_X.png').convert_alpha(),
|
||||
"Y": render.pg.image.load('images/XboxOne_Y.png').convert_alpha(),
|
||||
|
||||
"Dpad": render.pg.image.load('images/XboxOne_Dpad.png').convert_alpha(),
|
||||
"Dpad_Up": render.pg.image.load('images/XboxOne_Dpad_Up.png').convert_alpha(),
|
||||
"Dpad_Down": render.pg.image.load('images/XboxOne_Dpad_Down.png').convert_alpha(),
|
||||
"Dpad_Left": render.pg.image.load('images/XboxOne_Dpad_Left.png').convert_alpha(),
|
||||
"Dpad_Right": render.pg.image.load('images/XboxOne_Dpad_Right.png').convert_alpha(),
|
||||
|
||||
"Menu": render.pg.image.load('images/XboxOne_Menu.png').convert_alpha(),
|
||||
"Windows": render.pg.image.load('images/XboxOne_Windows.png').convert_alpha(),
|
||||
|
||||
"Left_Stick": render.pg.image.load('images/XboxOne_Left_Stick.png').convert_alpha(),
|
||||
"Left_Stick_Click": render.pg.image.load('images/XboxOne_Left_Stick_Click.png').convert_alpha(),
|
||||
"Right_Stick": render.pg.image.load('images/XboxOne_Right_Stick.png').convert_alpha(),
|
||||
"Right_Stick_Click": render.pg.image.load('images/XboxOne_Right_Stick_Click.png').convert_alpha(),
|
||||
|
||||
|
||||
"LB": render.pg.image.load('images/XboxOne_LB.png').convert_alpha(),
|
||||
"RB": render.pg.image.load('images/XboxOne_RB.png').convert_alpha(),
|
||||
"LT": render.pg.image.load('images/XboxOne_LT.png').convert_alpha(),
|
||||
"RT": render.pg.image.load('images/XboxOne_RT.png').convert_alpha()
|
||||
|
||||
}
|
||||
|
||||
ControllerSize = (render.width/2, render.width*(buttonImages['Controller'].get_height()/buttonImages['Controller'].get_width())/2)
|
||||
ControllerYOffset = (render.height-ControllerSize[1])/2
|
||||
global controllerRects
|
||||
controllerRects = {
|
||||
(0, render.topBarHeight+ControllerYOffset, ControllerSize[0], ControllerSize[1]),
|
||||
(ControllerSize[0], render.topBarHeight+ControllerYOffset, ControllerSize[0], ControllerSize[1])
|
||||
}
|
||||
|
||||
def refresh(self):
|
||||
global ogNodes
|
||||
global ogCtrlNodes
|
||||
global ogRotNodes
|
||||
|
||||
render.clear()
|
||||
render.drawField()
|
||||
if not buttonMode:
|
||||
global ogNodes
|
||||
global ogCtrlNodes
|
||||
global ogRotNodes
|
||||
|
||||
pointCounts = getBezierPointCounts()
|
||||
for i in range(0,len(ogCtrlNodes)):
|
||||
render.bezier(ogNodes[i], ogCtrlNodes[i], ogNodes[i+1], pointCounts[i])
|
||||
render.drawField()
|
||||
|
||||
pointCounts = getBezierPointCounts()
|
||||
for i in range(0,len(ogCtrlNodes)):
|
||||
render.bezier(ogNodes[i], ogCtrlNodes[i], ogNodes[i+1], pointCounts[i])
|
||||
|
||||
if selFrame != -1 and len(ogNodes) > 0:
|
||||
pos, rot = getRobotAtIndex(selFrame)
|
||||
render.robotSquare(pos, rot)
|
||||
else:
|
||||
renderXboxControllers()
|
||||
|
||||
if selFrame != -1 and len(ogNodes) > 0:
|
||||
pos, rot = getRobotAtIndex(selFrame)
|
||||
render.robotSquare(pos, rot)
|
||||
|
||||
reloadBar((0,0))
|
||||
render.update()
|
||||
@@ -253,7 +395,10 @@ class buttonEditor:
|
||||
|
||||
|
||||
def mouseDown(self, pos):
|
||||
if pos[1] > bottomBarRect[1]:
|
||||
if buttonMode:
|
||||
controllerClick(pos)
|
||||
self.refresh()
|
||||
elif pos[1] > bottomBarRect[1]:
|
||||
clickBar(pos, False)
|
||||
self.refresh()
|
||||
|
||||
@@ -292,6 +437,10 @@ class buttonEditor:
|
||||
elif key == render.pg.K_RIGHT and selFrame < displayTicks-1:
|
||||
selFrame += 1
|
||||
self.refresh()
|
||||
elif key == render.pg.K_e:
|
||||
global buttonMode
|
||||
buttonMode = not buttonMode
|
||||
self.refresh()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ clickIndex = -1
|
||||
render = None
|
||||
|
||||
|
||||
|
||||
|
||||
def refresh():
|
||||
render.clear()
|
||||
render.drawField()
|
||||
@@ -47,6 +49,8 @@ def refresh():
|
||||
render.circle(nodeColor, pos, nodeRadius)
|
||||
render.update()
|
||||
|
||||
|
||||
|
||||
def getElemAt(pos):
|
||||
for i in range(0,len(nodes)):
|
||||
if getDist(pos, nodes[i], nodeRadius):
|
||||
@@ -61,9 +65,13 @@ def getElemAt(pos):
|
||||
return 1, i
|
||||
return -1, -1
|
||||
|
||||
|
||||
|
||||
def getDist(pos1, pos2, dist):
|
||||
return math.sqrt(math.pow(pos1[0]-pos2[0], 2) + math.pow(pos1[1]-pos2[1], 2)) <= dist
|
||||
|
||||
|
||||
|
||||
def addNode(pos):
|
||||
nodes.append(pos)
|
||||
if len(nodes) > 1:
|
||||
@@ -76,6 +84,8 @@ def addNode(pos):
|
||||
nodeRotations.append(math.pi/2)
|
||||
refresh()
|
||||
|
||||
|
||||
|
||||
def nearestCirclePoint(center, pos, R):
|
||||
vX = pos[0] - center[0]
|
||||
vY = pos[1] - center[1]
|
||||
@@ -84,6 +94,8 @@ def nearestCirclePoint(center, pos, R):
|
||||
aY = center[1] + vY / magV * R
|
||||
return (aX, aY)
|
||||
|
||||
|
||||
|
||||
def points2rad(center, pos):
|
||||
diffX = center[0] - pos[0]
|
||||
diffY = center[1] - pos[1]
|
||||
@@ -91,6 +103,8 @@ def points2rad(center, pos):
|
||||
|
||||
class pathEditor:
|
||||
name = "Path Editor"
|
||||
|
||||
|
||||
def __init__(self, tmprender):
|
||||
# global screen
|
||||
# screen = tmpscreen
|
||||
@@ -99,6 +113,8 @@ class pathEditor:
|
||||
|
||||
refresh()
|
||||
|
||||
|
||||
|
||||
def mouseDown(self, pos):
|
||||
global clickType
|
||||
global clickIndex
|
||||
@@ -106,6 +122,8 @@ class pathEditor:
|
||||
if clickType == -1:
|
||||
addNode(pos)
|
||||
|
||||
|
||||
|
||||
def mouseUp(self, pos):
|
||||
global clickType
|
||||
global clickIndex
|
||||
@@ -113,16 +131,20 @@ class pathEditor:
|
||||
clickType = -1
|
||||
clickIndex = -1
|
||||
|
||||
|
||||
|
||||
def mouseMove(self, pos):
|
||||
if clickType != -1:
|
||||
if clickType == 0:
|
||||
nodes[clickIndex] = pos
|
||||
nodes[clickIndex] = pos
|
||||
if clickType == 1:
|
||||
curveEditPoints[clickIndex] = pos
|
||||
curveEditPoints[clickIndex] = pos
|
||||
if clickType == 2:
|
||||
nodeRotations[clickIndex] = points2rad(nodes[clickIndex], nearestCirclePoint(nodes[clickIndex], pos, rotNodeDist/render.offsetSize))
|
||||
nodeRotations[clickIndex] = points2rad(nodes[clickIndex], nearestCirclePoint(nodes[clickIndex], pos, rotNodeDist/render.offsetSize))
|
||||
refresh()
|
||||
|
||||
|
||||
|
||||
def doubleClick(self, pos):
|
||||
clickType, clickIndex = getElemAt(pos)
|
||||
if clickType == -1:
|
||||
@@ -139,8 +161,12 @@ class pathEditor:
|
||||
nodeRotations.pop(clickIndex)
|
||||
refresh()
|
||||
|
||||
|
||||
|
||||
def keyDown(self, key):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def load(self):
|
||||
refresh()
|
||||
@@ -15,6 +15,8 @@ nodeSquareWidth = 3
|
||||
nodeTickLength = 5
|
||||
|
||||
class render():
|
||||
|
||||
|
||||
def __init__(self, pg, screen, topBarHeight, bottomBarHeight):
|
||||
self.pg = pg
|
||||
self.screen = screen
|
||||
@@ -28,20 +30,32 @@ class render():
|
||||
|
||||
self.font = self.pg.font.Font(None, 25)
|
||||
|
||||
self.fieldImg = pg.image.load("frc2024.png").convert_alpha()
|
||||
self.fieldImg = pg.image.load("images/Field.png").convert_alpha()
|
||||
self.offsetSize = self.fieldImg.get_width() / self.width
|
||||
self.fieldImg = pg.transform.scale(self.fieldImg, (self.width, self.height))
|
||||
|
||||
self.elements = []
|
||||
|
||||
def invert(img):
|
||||
inv = pygame.Surface(img.get_rect().size, pygame.SRCALPHA)
|
||||
inv.fill((255,255,255,255))
|
||||
inv.blit(img, (0,0), None, BLEND_RGB_SUB)
|
||||
return inv
|
||||
|
||||
def line(self, color, pos1, pos2, width):
|
||||
self.pg.draw.line(self.screen, color, pos1, pos2, round(width/self.offsetSize))
|
||||
self.pg.draw.line(self.screen, color, pos1, pos2, round(width/self.offsetSize))
|
||||
|
||||
|
||||
|
||||
def circle(self, color, pos, radius):
|
||||
self.pg.draw.circle(self.screen, color, pos, radius/self.offsetSize)
|
||||
self.pg.draw.circle(self.screen, color, pos, radius/self.offsetSize)
|
||||
|
||||
|
||||
|
||||
def drawrect(self, color, rect):
|
||||
self.pg.draw.rect(self.screen, color, rect)
|
||||
self.pg.draw.rect(self.screen, color, rect)
|
||||
|
||||
|
||||
|
||||
def isInRect(self, pos, rect):
|
||||
return pos[0] >= rect[0] and \
|
||||
@@ -49,6 +63,13 @@ class render():
|
||||
pos[1] >= rect[1] and \
|
||||
pos[1] <= rect[1]+rect[3]
|
||||
|
||||
|
||||
|
||||
def image(self, img, rect):
|
||||
self.screen.blit(self.pg.transform.scale(img, (rect[2], rect[3])), rect)
|
||||
|
||||
|
||||
|
||||
def robotSquare(self, pos, rot):
|
||||
pos1 = ((math.sin(rot + math.pi*-0.25)*nodeSquareRadius/self.offsetSize) + pos[0],
|
||||
(math.cos(rot + math.pi*-0.25)*nodeSquareRadius/self.offsetSize) + pos[1])
|
||||
@@ -72,6 +93,8 @@ class render():
|
||||
self.line(nodeSquareColor, pos5, pos6, nodeSquareWidth*self.offsetSize)
|
||||
|
||||
|
||||
|
||||
|
||||
def bezier(self, p0, p1, p2, curvePointCount):
|
||||
#for p in [p0, p1, p2]:
|
||||
# pg.draw.circle(self.screen, (255, 255, 255), p, 5)
|
||||
@@ -82,35 +105,50 @@ class render():
|
||||
self.circle(curvePointColor, p2, curvePointRadius)
|
||||
#self.drawrect(curvePointColor, (round(px+0.5), round(py+0.5), curvePointRadius, curvePointRadius))
|
||||
|
||||
|
||||
|
||||
def clear(self):
|
||||
self.pg.draw.rect(self.screen, (0, 0, 0), self.rect)
|
||||
|
||||
|
||||
|
||||
def drawField(self):
|
||||
self.screen.blit(self.fieldImg, self.rect)
|
||||
|
||||
|
||||
|
||||
def renderElements(self, pos):
|
||||
for elem in self.elements:
|
||||
if elem['type'] == 'button':
|
||||
if elem['type'] == 'button' and elem['getIsVisible']():
|
||||
# print(elem['getIsSelected']())
|
||||
self.renderButton(elem['rect'], elem['text'], elem['getIsSelected'](), pos)
|
||||
|
||||
|
||||
|
||||
def clickElement(self, pos):
|
||||
for elem in self.elements:
|
||||
if elem['type'] == 'button' and self.isInRect(pos, elem['rect']):
|
||||
elem['onClick'](pos)
|
||||
|
||||
|
||||
|
||||
def update(self):
|
||||
self.pg.display.update()
|
||||
|
||||
def addButton(self, rect, text, getIsSelected, onClick):
|
||||
|
||||
|
||||
def addButton(self, rect, text, getIsSelected, getIsVisible, onClick):
|
||||
self.elements.append({
|
||||
"type": "button",
|
||||
"text": text,
|
||||
"getIsSelected": getIsSelected,
|
||||
"getIsVisible": getIsVisible,
|
||||
"onClick": onClick,
|
||||
"rect": rect
|
||||
})
|
||||
|
||||
|
||||
|
||||
def renderButton(self, rect, text, selected, mousePos):
|
||||
|
||||
# print(isInRect(mousePos, rect))
|
||||
|
||||