ppizarror / pygame-menu

A menu for pygame. Simple, and easy to use
https://pygame-menu.readthedocs.io/
Other
555 stars 141 forks source link

Add a menu border as part of the theme #390

Closed vnmabus closed 2 years ago

vnmabus commented 2 years ago

Is your feature request related to a problem? Please describe. I am trying to define a menu with a border, as in this example:

bildo

The borders are defined in this file:

dialog-borders01

Describe the solution you'd like I would want to be able to define a border for the menu, so that pygame-menu is able to tile it (as opposed to stretching it) and place the corners appropriately. Ideally this option could be made part of a theme.

Describe alternatives you've considered I tried defining that as a background image, but then I would need to define it with the right final dimensions or it would be stretched. I also tried using menu.get_scrollarea().get_decorator().add_callable, achieving the image above. The problem with this solution is that I cannot define that in a theme, forcing me to modify each menu separatedly or to create a subclass of Menu that applies this by default.

ppizarror commented 2 years ago

I'll add menu_border_width and menu_border_color. I think these two properties are sufficient

vnmabus commented 2 years ago

Would it allow using an image to define the border?

ppizarror commented 2 years ago

Do you have any code to place the image? If I detect the menu_border_color is "baseimage" instance I can execute such function inside the border. The "color" code is much easier, as I can use "rect.inflate" to fill a border

vnmabus commented 2 years ago

Yes. We are dealing with this problem because we wanted to rewrite Tuxemon's UI to use pygame-menu, instead of our own existing UI, but keeping the same look and feel.

I was doing a small test to see feasibility and difficulty of such a change. For that I reused the existing drawing code using menu.get_scrollarea().get_decorator().add_callable as I mentioned before. The actual code that draws the image and the borders is this one:

https://github.com/Tuxemon/Tuxemon/blob/bf96fbbf926df5e2f5b5c42e47037e57527db0f8/tuxemon/ui/draw.py#L85-L155

vnmabus commented 2 years ago

Is there something I can do to advance this issue?

ppizarror commented 2 years ago

Hi, sorry for the inactivity; I've been really short in my free time. I used your code and create new theme params border_color and border_width.

To test it, check new https://github.com/ppizarror/pygame-menu/pull/393, and use the following code:

theme = pygame_menu.themes.THEME_DEFAULT.copy()
theme.title_font_size = 15

# If you want a menu with border color
theme.border_color = 'red'
theme.border_width = 10 # In px
menu = pygame_menu.Menu('Menu with border color', 250, 250, theme=theme)
menu.mainloop(surface)

# Test with image
theme.border_color = pygame_menu.BaseImage(pygame_menu.baseimage.IMAGE_EXAMPLE_TILED_BORDER)
menu = pygame_menu.Menu('Menu with border image', 250, 250, theme=theme)
menu.mainloop(surface)

Let me know if this solves your issue 😄

ppizarror commented 2 years ago

Is there something I can do to advance this issue?

Hi @vnmabus , have you been able to test the new feature? Greetings!

vnmabus commented 2 years ago

The border color seems to work, although I couldn't make the image example work... It shows a menu without border to me.

ppizarror commented 2 years ago

The border color seems to work, although I couldn't make the image example work... It shows a menu without border to me.

You my friend @vnmabus have spotted an issue! I've already patched, now the code should work perfectly. For instance, you can use any BaseImage method, like scale, and it should work as intended:

theme = pygame_menu.themes.THEME_DEFAULT.copy()
theme.title_font_size = 15
theme.border_color = pygame_menu.BaseImage(pygame_menu.baseimage.IMAGE_EXAMPLE_TILED_BORDER)
theme.border_color.scale2x()
menu = pygame_menu.Menu('Menu with border image', 250, 250, theme=theme)
menu.mainloop(surface)

image

theme = pygame_menu.themes.THEME_DEFAULT.copy()
theme.title_font_size = 15
theme.border_color = pygame_menu.BaseImage(pygame_menu.baseimage.IMAGE_EXAMPLE_TILED_BORDER)
theme.border_color.scale(5, 5)
menu = pygame_menu.Menu('Menu with border image', 250, 250, theme=theme)
menu.mainloop(surface)

image

ppizarror commented 2 years ago

Greetings! @vnmabus, I will close this issue and publish it to PyPI. Feel free to create any issue to report bugs or new features.

vnmabus commented 2 years ago

Yeah, I didn't found any other bug for now. Thank you so much!

ppizarror commented 2 years ago

Uploaded! https://pypi.org/project/pygame-menu/4.2.6/

vnmabus commented 2 years ago

A related thing that would be useful is a way to query the size of the menu including the border, for placement purposes. Should I open a new issue for this?

ppizarror commented 2 years ago

A related thing that would be useful is a way to query the size of the menu including the border, for placement purposes. Should I open a new issue for this?

That's a nice addition. Let's make a new issue