Files
2020-07-29 12:59:12 +02:00

449 lines
12 KiB
Python

from pygame.locals import *
from .rect import Rect
from . import colors
import pygame
class Button(Rect):
"""Button using pygame and colors."""
def __init__(self,
text="button",
position=[0,0],
size=[300,50],
police="monospace",
text_size=50,
bold=False,
italic=False,
default_background_style=colors.WHITE,
hovered_background_style=colors.GREEN,
focused_background_style=colors.BLUE,
clicked_background_style=colors.RED,
default_text_style=colors.BLACK,
hovered_text_style=colors.BLACK,
focused_text_style=colors.BLACK,
clicked_text_style=colors.BLACK,
build=True):
"""Create a button."""
super().__init__(position,size)
self.text = text
self.police = police
self.text_size = text_size
self.bold = bold
self.italic = italic
self.default_background_style = default_background_style
self.hovered_background_style = hovered_background_style
self.focused_background_style = focused_background_style
self.clicked_background_style = clicked_background_style
self.default_text_style = default_text_style
self.hovered_text_style = hovered_text_style
self.focused_text_style = focused_text_style
self.clicked_text_style = clicked_text_style
self.hovered = False
self.focused = False
self.clicked = False
self.updateBackgroundSizes()
if build: self.build()
def build(self):
"""Buid a new surface."""
self.surface=pygame.Surface(self.size)
self.updateSurface()
def getFont(self):
"""Return a font."""
return pygame.font.SysFont(self.police,self.text_size,self.bold,self.italic)
def getTextStyle(self):
"""Return the style of the text."""
if self.clicked:
return self.clicked_text_style
elif self.focused:
return self.focused_text_style
elif self.hovered:
return self.hovered_text_style
else:
return self.default_text_style
def getBackgroundStyle(self):
"""Return the style of the background."""
if self.clicked:
return self.clicked_background_style
elif self.focused:
return self.focused_background_style
elif self.hovered:
return self.hovered_background_style
else:
return self.default_background_style
def updateBackgroundSizes(self):
"""Set the sizes of the background surfaces if they exist."""
if isinstance(self.clicked_background_style,pygame.Surface):
pygame.transform.scale(self.clicked_background_style,self.size)
if isinstance(self.focused_background_style,pygame.Surface):
pygame.transform.scale(self.focused_background_style,self.size)
if isinstance(self.hovered_background_style,pygame.Surface):
pygame.transform.scale(self.hovered_background_style,self.size)
if isinstance(self.default_background_style,pygame.Surface):
pygame.transform.scale(self.default_background_style,self.size)
def updateSurface(self):
"""Return the surface of the button."""
sx,sy=self.size
font_surface=self.font.render(self.text,True,self.text_style)
sfx,sfy=font_surface.get_size()
background_style=self.getBackgroundStyle()
if isinstance(background_style,pygame.Surface):
self.surface.blit(background_style)
else:
self.surface.fill(background_style)
self.surface.blit(font_surface,((sx-sfx)//2,(sy-sfy)//2))
def reset(self):
"""Reset the button."""
self.hovered=False
self.focused=False
self.clicked=False
def update(self,*args):
"""Update the button."""
self.updateStates(*args)
self.updateSurface()
def updateStates(self,position,click,focus,select):
"""Update the states of the button."""
self.focused=focus
if position in self:
self.hovered=True
if click:
self.focused=True
self.clicked=True
else:
self.clicked=False
else:
self.hovered=False
if select:
if focus:
self.clicked=True
def isColorStyle(self,object):
"""Determine if an object is a color."""
if type(object)==tuple:
if len(object)==3:
for i in range(3):
if not (0<=object[i]<256):
return False
return True
else:
return False
else:
return False
font=property(getFont)
text_style=property(getTextStyle)
background_style=property(getBackgroundStyle)
class Page(Rect):
"""Page using pygame, colors and window."""
def __init__(self,rect,buttons=[],background=None):
"""Create a page."""
self.buttons=buttons
self.focus=None
self.select=False
self.background=background
cdn=Rect.getCoordinatesFromRect(rect)
super().__init__(cdn[:2],cdn[2:])
self.spreadVerticalButtons()
def isColor(self,object):
"""Determine if an object is a color."""
if type(object) == tuple:
if len(object) == 3 or len(object) == 4:
for i in range(len(object)):
if not (0 <= object[i] < 256):
return False
return True
else:
return False
else:
return False
def spreadVerticalButtons(self):
"""Spread the buttons on the vertical evenly."""
l=len(self.buttons)
sx,sy=self.surface.get_size()
uy=sy//l
mx=sx//2
for i in range(l):
self.buttons[i].center=(mx,uy*(i+1/2))
def spreadHorizontalButtons(self):
"""Spread the buttons on the horizontal evenly."""
l=len(self.buttons)
sx,sy=self.surface.get_size()
ux=sx//l
my=sy//2
for i in range(l):
self.buttons[i].center=(ux*(i+1/2),my)
def showButtons(self):
"""Show the buttons on the surface."""
for button in self.buttons:
self.surface.blit(button.surface,button.position)
def __call__(self,window):
"""Execute the main loop with the window."""
while window:
self.events(window)
self.update(window)
self.show(window)
window.flip()
def events(self,window):
"""Deal with the events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
window.open = False
return
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
window.open = False
return
if event.key == K_DOWN or event.key == K_RIGHT:
if self.focus is not None:
self.focus = (self.focus+1) % len(self.buttons)
else:
self.focus=0
if event.key == K_UP or event.key == K_LEFT:
if self.focus is not None:
self.focus = (self.focus-1) % len(self.buttons)
else:
self.focus=0
if event.type == MOUSEMOTION:
self.motion = True
else:
self.motion = False
def update(self,window):
"""Update the page."""
self.updateStates(window)
self.updateSurface()
def updateStates(self,window):
"""Update the state of the page."""
self.cursor = window.point()
self.click = window.click()
keys = window.press()
self.select = bool(keys[K_RETURN]) or bool(keys[K_SPACE])
self.setFocus()
self.resetButtons()
self.updateButtons()
def setFocus(self):
"""Set the focus using the motion."""
if self.motion or self.click:
for i in range(len(self.buttons)):
if self.cursor in self.buttons[i]:
self.focus = i
def resetButtons(self):
"""Reset all the buttons."""
for i in range(len(self.buttons)):
self.buttons[i].reset()
def updateButtons(self):
"""Update a button."""
for i in range(len(self.buttons)):
focus = bool(self.focus == i)
self.buttons[i].update(self.cursor,self.click,focus,self.select)
def show(self,window):
"""Show the page by showing its components."""
self.showSurface(window)
self.showButtons(window)
def showSurface(self,window):
"""Show the surface."""
window.screen.blit(self.surface,(self.xmin,self.ymin))
def showButtons(self,context):
"""Show the buttons of the page."""
for i in range(len(self.buttons)):
context.screen.blit(self.buttons[i].surface,self.buttons[i].position)
def getSurface(self):
"""Return the surface of the page."""
surface = pygame.Surface(self.size)
if self.background is not None:
if self.isColor(self.background):
surface.fill(self.background)
else:
background = pygame.transform.scale(self.background,self.size)
surface.blit(background)
return surface
surface=property(getSurface)
"""
def action1():
pass
def action2():
pass
def action3():
pass
actions={
"key_action1":action1,
"key_action2":action2,
"key_action3":action3
}
tree={
"key_page1":{
"key1" : "action1",
"key2" : "action2",
"key3" : ""
}
"key_page2":{
"key1": "key_action3",
"key2": ""
}
}
def action1():
othello.plateau.grille=[]
buttons = { 1 : "Start",
11 : "Lancer",
12 : "Joueur blanc",
121 : "Humain",
122 : "Cyrano",
123 : "Retour vers joueur blanc",
13 : "Joueur noir",
131 : "Humain",
132 : "Cyrano",
133 : "Retour vers joueur noir",
14 : "Retour vers start",
2 : "Option",
21 : "Activer l'aide au mouvement", # cliquer sur ce bouton fait alterner un bouléen
22 : "Retour vers option",
3 : "Quitter" # cliquer ferme la fenetre
}
}
interactions_buttons={
"Humain" : choisirJoueurBlancHumain,
"Cyrano" :
}
pages={
"page1":Page
"page2":Page()
}
interactions = {
"page1":{
"Start" : clé page 2;
"Option" : clé page ;
"Quitter" : fermer la fenetre };
"page2":{
}
}
"""
class Menu:
def createFromButtonsHierarchy(buttons):
"""Create a page from a buttons dictionary."""
return Menu(pages,interactions)
def __init__(self,pages,tree,actions):
"""Create a menu."""
self.pages=pages #Dictionary
self.tree=tree
self.key=key
def __call__(self,window):
"""Load the page of key 'key'."""
while window.open:
self.page.events(window)
self.page.update(window)
self.update()
self.page.show(window)
window.screen.blit(self.page.surface,(0,0))
window.flip()
def update(self):
"""Update the menu after updating the page and its buttons in order to
take an action."""
button_key=self.checkButtons()
if button_key is not None:
self.tree[self.key]
def checkButtons(self):
"""Check if the buttons are being clicked."""
for i in range(len(self.page.buttons)):
if self.page.buttons[i].clicked:
return i
key_action=self.tree[self.key]
action=self.actions[key_action]
action()
def getPage(self):
"""Return the current page."""
return self.pages[self.key]
page=property(getPage)
if __name__=="__main__":
from .window import Window
window=Window("Page")
buttons=[Button(t) for t in ["oui","non","peut etre","pourquoi pas"]]
page=Page(window.size,buttons)
page(window)