From 530752aa6ad52b6ba0bebbf23d25700d90c3e1c3 Mon Sep 17 00:00:00 2001 From: "Tsunami014 (Max)" Date: Mon, 16 Dec 2024 09:05:41 +1100 Subject: [PATCH] =?UTF-8?q?feat(graphics):=20=E2=9C=A8=20Added=20a=20check?= =?UTF-8?q?box?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BlazeSudio/graphics/GUI/elements.py | 65 +++++++++++++++++++++++++++++ BlazeSudio/graphics/options.py | 15 ++++--- demos.py | 6 +-- 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/BlazeSudio/graphics/GUI/elements.py b/BlazeSudio/graphics/GUI/elements.py index 44a785f..e91d194 100644 --- a/BlazeSudio/graphics/GUI/elements.py +++ b/BlazeSudio/graphics/GUI/elements.py @@ -2,6 +2,7 @@ import pygame from typing import Callable from string import printable +from random import random from BlazeSudio.graphics import mouse, options as GO from BlazeSudio.graphics.GUI.base import Element, ReturnGroup, ReturnState from BlazeSudio.graphics.GUI.theme import GLOBALTHEME @@ -9,6 +10,7 @@ __all__ = [ 'Switch', + 'Checkbox', 'InputBox', 'NumInputBox', 'Empty', @@ -74,6 +76,69 @@ def set(self, newState): """Set the state of the switch (on or off)""" self.state = newState +class Checkbox(Element): + type = GO.TCHECKBOX + def __init__(self, G, pos: GO.P___, size=40, thickness=5, check_size=15, radius=5, default=False): + """ + A checkbox that can be either checked or unchecked. + + Args: + G (Graphic): The graphic screen to attach to. + pos (GO.P___): The position of this element in the screen. + size (int, optional): The size of this element. Defaults to 40. + thickness (int, optional): The thickness of the lines. Defaults to 5. + check_size (int, optional): The size of the check mark arrow. Defaults to 20. + radius (int, optional): The border radius of the drawn boxes. Defaults to 5. + default (bool, optional): Whether the checkbox is either on or off on creation. Defaults to False. + """ + self.thickness = thickness + self.BR = radius + self.Csize = check_size + self.rerandomise() + super().__init__(G, pos, (size, size)) + self.state = default + + def rerandomise(self): + self.randoms = [random()+1, random()+1, random()+3, random()*2+4] + + def update(self, mousePos, events): + x, y = self.stackP() + if mousePos: + mcollides = pygame.Rect(x, y, *self.size).collidepoint(mousePos) + else: + mcollides = False + if not self.G.pause: + if mcollides: + if pygame.mouse.get_pressed()[0]: + mouse.Mouse.set(mouse.MouseState.CLICKING) + else: + mouse.Mouse.set(mouse.MouseState.HOVER) + for event in events: + if event.type == pygame.MOUSEBUTTONDOWN and \ + event.button == pygame.BUTTON_LEFT and mcollides: + self.state = not self.state + self.rerandomise() + return ReturnState.CALL + + def draw(self): + x, y = self.stackP() + pygame.draw.rect(self.G.WIN, (125, 125, 125), pygame.Rect(x, y, *self.size), self.thickness, self.BR) + if self.state: + midp = (x+self.size[0]/2, y+self.size[1]-(self.size[1]/self.randoms[3])) + p1 = (midp[0]-self.Csize*self.randoms[0], midp[1]-self.Csize) + p2 = (midp[0]+self.Csize*self.randoms[1], midp[1]-self.Csize*self.randoms[2]) + pygame.draw.line(self.G.WIN, GO.CGREEN, p1, midp, self.thickness+1) + pygame.draw.line(self.G.WIN, GO.CGREEN, midp, p2, self.thickness+1) + for p in (p1, midp, p2): + pygame.draw.circle(self.G.WIN, GO.CGREEN, p, self.thickness//2+1) + + def get(self): + """Get the state of the checkbox (on or off)""" + return self.state + def set(self, newState): + """Set the state of the checkbox (on or off)""" + self.state = newState + # InputBoxes code modified from https://stackoverflow.com/questions/46390231/how-can-i-create-a-text-input-box-with-pygame # TODO: A text cursor diff --git a/BlazeSudio/graphics/options.py b/BlazeSudio/graphics/options.py index e253f0b..af3d61d 100644 --- a/BlazeSudio/graphics/options.py +++ b/BlazeSudio/graphics/options.py @@ -4,6 +4,8 @@ import pygame.freetype from string import printable +# TODO: Make these all enums + # TODO: Modify the __str__ and __repr__ of the class to a name def Base(cls=None, default=True, str=True, addhash=True): def wrap(clss): @@ -407,12 +409,13 @@ def __repr__(self): return str(self) TNUMBOX = T___(2, 'Numbox' ) TTEXTBOX = T___(3, 'Textbox' ) TSWITCH = T___(4, 'Switch' ) -TFRAME = T___(5, 'Frame' ) -TLAYOUT = T___(6, 'Layout' ) -TSTATIC = T___(7, 'Static' ) -TCOLOURPICK = T___(8, 'ColourPick') -TTOAST = T___(9, 'Toast' ) -TEMPTY = T___(10, 'Empty' ) +TCHECKBOX = T___(5, 'Checkbox' ) +TFRAME = T___(6, 'Frame' ) +TLAYOUT = T___(7, 'Layout' ) +TSTATIC = T___(8, 'Static' ) +TCOLOURPICK = T___(9, 'ColourPick') +TTOAST = T___(10, 'Toast' ) +TEMPTY = T___(11, 'Empty' ) # Resizes diff --git a/demos.py b/demos.py index 9b1d311..41dde5b 100644 --- a/demos.py +++ b/demos.py @@ -115,9 +115,9 @@ def _LoadUI(self): # Load the graphics in! self['speshs'].append(L) self.sw = GUI.Switch(L, L.LP) L.grid = [ - [GUI.Text(L, L.LP, 'HI'), GUI.Text(L, L.LP, 'HELLO'), GUI.Text(L, L.LP, 'BYE')], - [GUI.Text(L, L.LP, 'HEHE'), GUI.Text(L, L.LP, 'YES'), GUI.Text(L, L.LP, 'NO')], - [GUI.Text(L, L.LP, 'HAVE'), GUI.Text(L, L.LP, 'A'), GUI.Text(L, L.LP, 'NICEDAY')], + [GUI.Text(L, L.LP, 'HI'), None, GUI.Text(L, L.LP, 'BYE')], + [GUI.Text(L, L.LP, 'YES'), GUI.Checkbox(L, L.LP), GUI.Text(L, L.LP, 'NO')], + [GUI.Checkbox(L, L.LP, 20, check_size=10), GUI.Checkbox(L, L.LP, thickness=2), GUI.Checkbox(L, L.LP, check_size=40)], [GUI.Button(L, L.LP, GO.CORANGE, 'Hello!'), None, self.sw] ]