MyreMylar / pygame_gui

A GUI system for pygame.
MIT License
698 stars 83 forks source link

Move the sliding_button of the ui_horizontal_slider by a fixed value each time the left_button/right_button is pressed #193

Closed maky-hnou closed 2 years ago

maky-hnou commented 3 years ago

Hello, I've been struggling with creating UI components using pygame, till I found pygame_gui. So thank for making is easier.
I've been trying pygame_gui for few days to discover its functionalities.
However, I've been stuck in trying to move the sliding_button of the ui_horizontal_slider by a fixed value each time the left_button/right_button is pressed. Here is a brief description of what I want to do:
I created a horizontal slider. Let's say that the value_range is [5, 10] and the start_value is 5. I want that the slider value get's incremented by 1 every time the right_button of the slider is pressed (till it reaches 10) and the same when pressing the left_button of the slider, till it reaches 5.
I looked in to the code, and I couldn't find the option of moving the sliding_button by a fixed value. So I tried to create one, but it didn't work: when I click on the left/right button just for once, the sliding_button reaches the limit directly.
Here is the code I am using:

import pygame
from pygame_gui import UIManager, PackageResource

from pygame_gui.elements import UIHorizontalSlider

class SlideBar():
    def __init__(self, ui_manager, screen, screen_width, screen_height):
        self.ui_manager = ui_manager
        self.screen = screen
        self.screen_width = screen_width
        self.screen_height = screen_height

    def recreate_ui(self):
        self.ui_manager.set_window_resolution(
            (self.screen_width, self.screen_height))
        self.ui_manager.clear_and_reset()

    def create_slide_bar(self, pos_x, pos_y, init_value, min_v, max_v):
        self.test_slider = UIHorizontalSlider(
            pygame.Rect((int(pos_x),
                         int(pos_y)),
                        (240, 25)), init_value, (min_v, max_v),
            self.ui_manager, object_id='#cool_slider')
        return self.test_slider

    def update_slider(self, slide_bar):
        value_range = slide_bar.value_range[1] -\
            slide_bar.value_range[0]
        scroll_range = slide_bar.right_limit_position -\
            slide_bar.left_limit_position
        if slide_bar.left_button is not None and (
                slide_bar.left_button.held and
                slide_bar.scroll_position >
                slide_bar.left_limit_position):
            slide_bar.scroll_position -= scroll_range / value_range
            slide_bar.current_value -= 1
        elif slide_bar.right_button is not None and (
                slide_bar.right_button.held and
                slide_bar.scroll_position <
                slide_bar.right_limit_position):
            slide_bar.scroll_position += scroll_range / value_range
            slide_bar.current_value += 1

if __name__ == '__main__':
    pygame.init()
    screen_width = 800
    screen_height = 600
    screen = pygame.display.set_mode((screen_width, screen_height))
    ui_manager = UIManager((screen_width, screen_height),
                           PackageResource(package='data.themes',
                                           resource='theme_2.json'))
    background_surface = pygame.Surface((screen_width, screen_height))
    background_surface.fill(
        ui_manager.get_theme().get_colour('dark_bg'))
    app = SlideBar(ui_manager, screen, screen_width, screen_height)
    app.recreate_ui()
    slide_bar1 = app.create_slide_bar(100, 120, 5, 5, 10)
    running = True
    while running:

        # check for events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            ui_manager.process_events(event)
        # respond to input
        ui_manager.update(0.001)
        app.update_slider(slide_bar1)
        print(slide_bar1.scroll_position, slide_bar1.current_value)

        # draw graphics
        screen.blit(background_surface, (0, 0))
        ui_manager.draw_ui(screen)

        pygame.display.update()

Is it possible to move the sliding_button by a fixed value?

MyreMylar commented 3 years ago

Is it possible to move the sliding_button by a fixed value?

Not easily right now, it is one of the niggly things on my mental todo list to fix up. I think I'd like it to work with a little 'grace period' so if you just push down and release the mouse button quickly it moves up by a fixed (definable - with a default) increment but if you hold the mouse button longer than 0.5 seconds it starts increasing at a fairly fast clip like now.

Thanks for the issue though, it will likely remind me when I go round doing a polishing pass on some of the older UI elements.

If you want to implement it yourself for your application you could likely subclass the element as MakyUISlider and override just the process_events() and update() methods to make these changes (That's just from memory I haven't looked at this yet).