diff --git a/docs.md b/docs.md new file mode 100644 index 0000000..295d625 --- /dev/null +++ b/docs.md @@ -0,0 +1,217 @@ +# **PyGUI Documentation** + +## **1. Initialization and Cleanup** + +You must initialize `pygui` before use and quit when you're done with the library. + +### **Initialization:** + +```python +import pygui + +# Initialize PyGUI +pygui.init_pygui() +``` + +### **Cleanup:** + +```python +# When you're done with PyGUI +pygui.quit_pygui() +``` + +--- + +### **2. Button** + +A button that can detect mouse clicks. + +#### **Constructor:** + +```python +pygui.Button(text, pos, size) +``` + +- **text**: `str` - The text displayed on the button. +- **pos**: `tuple(int, int)` - The position of the button `(x, y)`. +- **size**: `tuple(int, int)` - The size of the button `(width, height)`. + +#### **Example:** + +```python +button = pygui.Button("Click Me", (100, 100), (200, 50)) + +if button.call(screen): + print("Button clicked!") +``` + +--- + +### **3. Slider** + +A slider allows the user to adjust a value between a minimum and maximum range. + +#### **Slider Constructor:** + +```python +pygui.Slider(pos, size, min_value=0, max_value=100, start_value=50) +``` + +- **pos**: `tuple(int, int)` - The position of the slider `(x, y)`. +- **size**: `tuple(int, int)` - The size of the slider `(width, height)`. +- **min_value**: `float` - Minimum value of the slider. +- **max_value**: `float` - Maximum value of the slider. +- **start_value**: `float` - The initial value of the slider. + +#### **Slider Example:** + +```python +slider = pygui.Slider((100, 200), (200, 20), min_value=0, max_value=10, start_value=5) +current_value = slider.call(screen) +print(f"Slider Value: {current_value}") +``` + +--- + +### **4. Checkbox** + +A checkbox element allows for toggling between checked and unchecked states. + +#### **Checkbox Constructor:** + +```python +pygui.Checkbox(label, pos, checked=False) +``` + +- **label**: `str` - The label displayed next to the checkbox. +- **pos**: `tuple(int, int)` - The position of the checkbox `(x, y)`. +- **checked**: `bool` - Initial state of the checkbox (default is `False`). + +#### **Checkbox Example:** + +```python +checkbox = pygui.Checkbox("Enable Feature", (100, 250), checked=True) + +if checkbox.call(screen): + print(f"Checkbox state: {checkbox.checked}") +``` + +--- + +### **5. TextInput** + +A text input field that allows users to type text. + +#### **TextInput Constructor:** + +```python +pygui.TextInput(pos, size, initial_text="") +``` + +- **pos**: `tuple(int, int)` - The position of the text input field `(x, y)`. +- **size**: `tuple(int, int)` - The size of the input box `(width, height)`. +- **initial_text**: `str` - The initial text inside the input field (default is an empty string). + +#### **TextInput Example:** + +```python +text_input = pygui.TextInput((100, 300), (200, 40), initial_text="Hello!") + +text_value = text_input.call(screen, event_list) +print(f"Text Input Value: {text_value}") +``` + +--- + +### **6. Label** + +A label is a simple text display. + +#### **Label Constructor:** + +```python +pygui.Label(text, pos, font_size=24, color=(255, 255, 255)) +``` + +- **text**: `str` - The text displayed in the label. +- **pos**: `tuple(int, int)` - The position of the label `(x, y)`. +- **font_size**: `int` - The font size (default is 24). +- **color**: `tuple(int, int, int)` - The color of the text `(R, G, B)`. + +#### **Label Example:** + +```python +label = pygui.Label("This is a label", (100, 50)) + +label.call(screen) +``` + +--- + +### **7. Window** + +A window element that can contain multiple GUI elements, such as sliders, buttons, and checkboxes. + +#### **Window Constructor:** + +```python +pygui.Window(title, pos, size, elements=None, fixed=False) +``` + +- **title**: `str` - The title of the window. +- **pos**: `tuple(int, int)` - The position of the window `(x, y)`. +- **size**: `tuple(int, int)` - The size of the window `(width, height)`. +- **elements**: `list` - A list of GUI elements to be included in the window. +- **fixed**: `bool` - Whether the window can be moved by the user (default is `False`). + +#### **Window Example:** + +```python +window = pygui.Window("My Window", (100, 100), (300, 200), elements=[button, slider, checkbox]) + +window.call(screen) +``` + +--- + +### **Example Usage** + +Here’s an example of how you can combine these elements into a basic GUI: + +```python +import pygame +import pygui + +# Initialize Pygame and PyGUI +pygui.init_pygui() +pygame.init() + +# Create screen +screen = pygame.display.set_mode((800, 600)) + +# Create GUI elements +button = pygui.Button("Click Me", (100, 100), (200, 50)) +slider = pygui.Slider((100, 200), (200, 20), min_value=0, max_value=10, start_value=5) +checkbox = pygui.Checkbox("Enable Feature", (100, 250), checked=True) +label = pygui.Label("This is a label", (100, 50)) +window = pygui.Window("Control Window", (400, 100), (300, 400), elements=[button, slider, checkbox, label]) + +# Main loop +running = True +while running: + screen.fill((30, 30, 30)) # Clear the screen with a dark color + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + # Call the window and its elements + window.call(screen) + + # Update display + pygame.display.flip() + +# Quit PyGUI and Pygame +pygui.quit_pygui() +pygame.quit() +``` diff --git a/pygui.py b/pygui.py index b8141ff..de8d183 100644 --- a/pygui.py +++ b/pygui.py @@ -7,8 +7,16 @@ def _load_colors(file_path='pygui_colors.json'): if not os.path.exists(file_path): print(f"[pygui] Color configuration file '{file_path}' not found.") else: + print(f"[pygui] Loading Color Config '{file_path}'") with open(file_path, 'r') as file: colors = json.load(file) + + print(f"[pygui] Color config Data:") + print(f" name: {colors['meta'].get('name', 'N/A')}") + print(f" description: {colors['meta'].get('description','N/A')}") + print(f" version: {colors['meta'].get('version','N/A')}") + print(f" link: {colors['meta'].get('link','N/A')}") + return colors # Load the colors at the start of the program @@ -245,13 +253,15 @@ class Knob: self.dragging = False # Track if the knob is being dragged self.last_mouse_y = None # To track the previous mouse y-position self.type = Knob + + self.angle_offset = -(self.min_angle + self.max_angle) / 2 def call(self, screen): """Draw the knob and handle rotation.""" - # Get the current mouse position and mouse click status + # Get the current mouse position and mouse click status mouse_pos = pygame.mouse.get_pos() mouse_click = pygame.mouse.get_pressed()[0] - + # Check if the knob is clicked (or already being dragged) if self.dragging: if not mouse_click: # Stop dragging if mouse is released @@ -261,31 +271,36 @@ class Knob: if self.last_mouse_y is not None: mouse_y_delta = mouse_pos[1] - self.last_mouse_y self.angle -= mouse_y_delta * self.sensitivity # Rotate angle based on vertical mouse movement - + # Ensure the angle is clamped between min_angle and max_angle self.angle = max(self.min_angle, min(self.angle, self.max_angle)) - + self.last_mouse_y = mouse_pos[1] # Update the last Y position of the mouse - + # Check for initial click to start dragging elif self.rect.collidepoint(mouse_pos) and mouse_click: self.dragging = True self.last_mouse_y = mouse_pos[1] # Start dragging, save the initial mouse Y position - + # Draw the knob (as a circle) pygame.draw.circle(screen, (255, 255, 255), self.rect.center, self.radius, 2) - - # Draw the rect around the knob for debugging purposes - #pygame.draw.rect(screen, (0, 255, 255), self.rect, 1) - - # Draw a "needle" to indicate the current angle + + # Adjust the needle angle so it starts facing up (90 degrees) and rotates left or right. + visual_angle = self.angle - 90 # Subtract 90 degrees to make it face up + + # Convert visual angle to radians for calculation needle_length = self.radius - 10 - needle_angle_rad = math.radians(self.angle) + needle_angle_rad = math.radians(visual_angle+self.angle_offset) + + # Calculate needle's end position based on the adjusted angle needle_x = self.rect.center[0] + needle_length * math.cos(needle_angle_rad) - needle_y = self.rect.center[1] - needle_length * math.sin(needle_angle_rad) + needle_y = self.rect.center[1] + needle_length * math.sin(needle_angle_rad) + + # Draw the "needle" to indicate the current angle pygame.draw.line(screen, (255, 0, 0), self.rect.center, (needle_x, needle_y), 3) - - return self.angle + + return self.angle # Return the unmodified angle for internal logic + def move(self, new_pos): """Move the knob to a new position.""" diff --git a/pygui_colors.json b/pygui_colors.json index 58420cc..afecf06 100644 --- a/pygui_colors.json +++ b/pygui_colors.json @@ -1,18 +1,35 @@ { + "meta":{ + "name":"Orange and Black", + "description":"Orange and Black theme for PyGUI", + "version":1.0, + "link":"https://github.com/OusmBlueNinja/pygui" + }, "label_colors": { - "default": [255, 255, 255], - "header": [70, 70, 70], - "highlight": [255, 0, 0], - "background": [50, 50, 50], - "button_hover": [100, 100, 100] + "default": [240, 240, 240], + "header": [50, 50, 50], + "highlight": [0, 123, 255], + "background": [40, 40, 40], + "button_hover": [80, 80, 80] }, "gui_color": { - "background":[70,70,70], - "title": [100,100,100], - "title_text":[255,255,255] + "background": [30, 30, 30], + "title": [45, 45, 45], + "title_text": [255, 255, 255] }, "slider_color": { - "background":[50,200,50], - "knob_color": [255,255,255] + "background": [100, 100, 100], + "knob_color": [255, 165, 0] + }, + "button_colors": { + "default": [70, 70, 70], + "hover": [90, 90, 90], + "active": [0, 123, 255], + "text": [255, 255, 255] + }, + "checkbox_colors": { + "box": [100, 100, 100], + "checkmark": [0, 255, 0], + "hover": [80, 80, 80] } }