Custom GUI - Button and slider alignment/positioning

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
BBN_VN
Newbie
Posts: 16
Joined: Sat Feb 20, 2021 1:33 pm
Contact:

Custom GUI - Button and slider alignment/positioning

#1 Post by BBN_VN »

Hi all. I could use a little help with something. Short version of the question is, I'm working on a customize GUI and am working with a graphic artist who has worked up some great mockups and assets for me. I'm about 90% of the way there getting this stuff into Ren'Py, but am stumbling over how to get the buttons and sliders to line up where I want them.

With a focus on the buttons and the sliders (not the menu at the bottom or spacing of the boxes), this is the mockup I am trying to get towards, provided by the artist working in Photoshop.

Goal
Image

Current State
Image

As you can see, in the current state, the buttons aren't vertically aligned with the center of the text, and the thumb for the slider is positioned below the bar. Any suggestions on how I change this?

I've been poking at the settings in the GUI and trying to find something in the documentation and Youtube tutorials, but have not had much luck.

Thank you!

philat
Eileen-Class Veteran
Posts: 1926
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Custom GUI - Button and slider alignment/positioning

#2 Post by philat »

Hard to say without either your assets or your code, but in general try looking into align properties (https://www.renpy.org/doc/html/style_pr ... rty-yalign) or gutter properties (https://www.renpy.org/doc/html/style_pr ... top_gutter). In the case of the bar, it might simply be easier to have the bar image be the correct height with blank space on the top and bottom.

User avatar
m_from_space
Eileen-Class Veteran
Posts: 1006
Joined: Sun Feb 21, 2021 3:36 am
Contact:

Re: Custom GUI - Button and slider alignment/positioning

#3 Post by m_from_space »

BBN_VN wrote: Mon Apr 29, 2024 10:27 pm I've been poking at the settings in the GUI and trying to find something in the documentation and Youtube tutorials, but have not had much luck.

Thank you!
Very neat design you got there as your goal! Immediately gives off werewolf vibes, not even reading about "weresex". xD

So one thing that the GUI won't be enough for is having the slider thumbs overlapping the label text. For example using a single vbox you cannot have "Music Volume" as text and then following a slider bar with a thumb that would overlap the text. You have to make two vbox overlap for that, which you cannot simply define inside GUI elements. You have to alter the preferences screen inside <screens.rpy>

Example that could make sure your thumbs will overlap with the text. You just have to adjust the position and whatnot of course:

Code: Select all

screen preferences():
    tag menu
    use game_menu(_("Preferences"), scroll="viewport"):
        # the vbox holding the text
        vbox:
            pos (1000, 100)
            label _("MUSIC VOLUME")
            # maybe insert some space in between
            null height 10
            label _("SOUND VOLUME")
            null height 10
            label _("EXPLICIT VOLUME")
        # the vbox holding the sliders
        vbox:
            pos (1000, 150)
            bar value Preference("music volume") style_prefix "slider"
            null height 5
            # the other sliders following
An easy way to adjust the text next to the radiobuttons is to use an yoffset or alter the borders inside gui.rpy

Play around with this inside <gui.rpy> (this might look different in your case and by default, this is just my entry):

Code: Select all

define gui.radio_button_borders = Borders(72, 6, 6, 6)
or add an offset in <screens.rpy> (find the style first, it already exists, just without the offset):

Code: Select all

style radio_button_text:
    properties gui.button_text_properties("radio_button")
    yoffset -15

BBN_VN
Newbie
Posts: 16
Joined: Sat Feb 20, 2021 1:33 pm
Contact:

Re: Custom GUI - Button and slider alignment/positioning

#4 Post by BBN_VN »

@philat: Thanks for the reply. Currently, other than hboxes, vboxes, tossing frames, and the menu bar at the bottom, the code is out of the box. I poked around at the gui borders for buttons and sliders thinking that might do something, but it didn't. I'm happy to share, but not even sure which parts to share.

@m_from_space: Thanks for this! I feel really lucky to have found the artist I'm working with. He took a kind of vague concept and has really run with it. And sorry for the NSFW reference. 😂 Oops!

That makes a lot of sense about the slider overlapping the text. I hadn't thought about that but I'm sure that's part of it.

I'll try these suggestions and links, and see what I can come up with. Very much appreciate the replies. 👍

BBN_VN
Newbie
Posts: 16
Joined: Sat Feb 20, 2021 1:33 pm
Contact:

Re: Custom GUI - Button and slider alignment/positioning

#5 Post by BBN_VN »

m_from_space wrote: Tue Apr 30, 2024 7:28 am *snip*
EDIT: Made some progress since originally posted, so I've revised the following with the new information.

First, again, thank you for these suggestions and links. I've made some good progress (I think) using the yoffset for the radio and check buttons. I also put the labels and sliders for audio and text speed into separate, overlapping vboxes. I've made a lot of progress, although the code may be inelegant and brute force.

I've put my code below (or, at least, what I think could be relevant).

Current challenges:
1. The thumb creates a dead space on the slider even though the thumb has a transparent background. I've tried using thumb_offset, but it hasn't made any change. Perhaps I'm putting the code in the wrong space or wrong format?

Image

Fully recognize my code is likely crap. I have no background in programming or software except for my work on this VN, so I'm learning as I go. I'm completely open to constructive criticism.
GUI Code
Note: Slider bar pngs are actually 130 pixels in height, but 70 seemed to get the thumb at the right location

Code: Select all

## Bars, Scrollbars, and Sliders ###############################################
##
## These control the look and size of bars, scrollbars, and sliders.
##
## The default GUI only uses sliders and vertical scrollbars. All of the other
## bars are only used in creator-written screens.

## The height of horizontal bars, scrollbars, and sliders. The width of vertical
## bars, scrollbars, and sliders.
define gui.bar_size = 38
define gui.scrollbar_size = 18
define gui.slider_size = 70

## True if bar images should be tiled. False if they should be linearly scaled.
define gui.bar_tile = False
define gui.scrollbar_tile = False
define gui.slider_tile = False

## Horizontal borders.
define gui.bar_borders = Borders(0, 0, 0, 0)
define gui.scrollbar_borders = Borders(0, 0, 0, 0)
define gui.slider_borders = Borders(0, 0, 0, 0)

## Vertical borders.
define gui.vbar_borders = Borders(0, 0, 0, 0)
define gui.vscrollbar_borders = Borders(0, 0, 0, 0)
define gui.vslider_borders = Borders(0, 0, 0, 0)

## What to do with unscrollable scrollbars in the gui. "hide" hides them, while
## None shows them.
define gui.unscrollable = "hide"
Screens Code

Code: Select all

creen game_menu(title, scroll=None, yinitial=0.0, spacing=0):

    style_prefix "game_menu"

    if main_menu:
        add gui.main_menu_background
    else:
        add gui.game_menu_background

    vbox:
        style "game_menu_outer_frame"

        vbox:        
            xalign 0.5
            yalign 0.5
            style "game_menu_content_frame"
            
        
            if scroll == "viewport":

                viewport:
                    yinitial yinitial
                    scrollbars "vertical"
                    mousewheel True
                    draggable True
                    pagekeys True

                    side_yfill False

                    vbox:
                        spacing spacing

                        transclude

            elif scroll == "vpgrid":

                vpgrid:
                    cols 1
                    yinitial yinitial

                    scrollbars "vertical"
                    mousewheel True
                    draggable True
                    pagekeys True

                    side_yfill False

                    spacing spacing

                    transclude

            else:

                transclude

    # textbutton _("Music Room") action ShowMenu("music_room",mr=music_room)

    add "gui/custom/divider.png" ypos 0.83 xcenter 0.5

    ## order, left to right:  Main Menu, Options, Help, Save, RETURN, Load, History, About, Quit

    imagebutton auto "gui/bbn_buttons/Start_%s.png":
        xalign 0.5 
        yalign 0.95
        hover_sound "audio/gui/hover.ogg"
        activate_sound "audio/gui/select-start.ogg"
        action Start()

    imagebutton auto "gui/bbn_buttons/Load_%s.png":
        xpos 700
        ypos 990
        hover_sound "audio/gui/hover.ogg"
        activate_sound "audio/gui/select-menu.ogg"
        action ShowMenu("load")

    imagebutton auto "gui/bbn_buttons/Options_%s.png":
        xpos 1100
        ypos 990
        hover_sound "audio/gui/hover.ogg"
        activate_sound "audio/gui/select-menu.ogg"
        action ShowMenu("preferences")

    imagebutton auto "gui/bbn_buttons/About_%s.png":
        xpos 1320
        ypos 990
        hover_sound "audio/gui/hover.ogg"
        activate_sound "audio/gui/select-menu.ogg"
        action ShowMenu("about")

    if renpy.variant("pc") and not renpy.variant("mobile"):

        imagebutton auto "gui/bbn_buttons/Help_%s.png":
            xpos 550
            ypos 990
            hover_sound "audio/gui/hover.ogg"
            activate_sound "audio/gui/select-menu.ogg"
            action ShowMenu("help")
        
        imagebutton auto "gui/bbn_buttons/Gallery_%s.png":
            xpos 350
            ypos 990
            hover_sound "audio/gui/hover.ogg"
            activate_sound "audio/gui/select-menu.ogg"
            action ShowMenu("gallery")
        
        imagebutton auto "gui/bbn_buttons/Quit_%s.png":
            xpos 1500
            ypos 990
            hover_sound "audio/gui/hover.ogg"
            action Quit(confirm=not main_menu)

    if renpy.variant("mobile"):
        imagebutton auto "gui/bbn_buttons/Gallery_%s.png":
            xpos 500
            ypos 990
            hover_sound "audio/gui/hover.ogg"
            activate_sound "audio/gui/select-menu.ogg"
            action ShowMenu("gallery")

    textbutton _("Return"):
        style "return_button"

        action Return()

    label title

    if main_menu:
        key "game_menu" action ShowMenu("main_menu")


style game_menu_outer_frame is empty
style game_menu_navigation_frame is empty
style game_menu_content_frame is empty
style game_menu_viewport is gui_viewport
style game_menu_side is gui_side
style game_menu_scrollbar is gui_vscrollbar

style game_menu_label is gui_label
style game_menu_label_text is gui_label_text

style return_button is navigation_button
style return_button_text is navigation_button_text

style game_menu_outer_frame:
    bottom_padding 45
    top_padding 180

    background "gui/overlay/game_menu_background.png"

#style game_menu_navigation_frame:
#    xsize 420
#    yfill True

style game_menu_content_frame:
    left_margin 30
    right_margin 30
    top_margin 15

style game_menu_viewport:
    #xsize 1380
    xsize 1800

style game_menu_vscrollbar:
    unscrollable gui.unscrollable

style game_menu_side:
    spacing 15

style game_menu_label:
    xpos 75
    ysize 180

style game_menu_label_text:
    size gui.title_text_size
    color gui.accent_color
    yalign 0.5

style return_button:
    xpos gui.navigation_xpos
    yalign 1.0
    yoffset -45
    
    ## Preferences screen ##########################################################
##
## The preferences screen allows the player to configure the game to better suit
## themselves.
##
## https://www.renpy.org/doc/html/screen_special.html#preferences

screen preferences():

    tag menu

    use game_menu(_(""), scroll=None):

        hbox:
            add "gui/custom/header_options_crop.png":
                xpos 100
                
        hbox:
            xpos 300

            vbox:
                #xalign 0.5
                #yalign 0.5
                vbox:

                    if renpy.variant("pc") or renpy.variant("web"):

                        vbox:
                            style_prefix "radio"
                            label _("DISPLAY")
                            textbutton _("Window") action Preference("display", "window"):
                                ypos 5
                            textbutton _("Fullscreen") action Preference("display", "fullscreen")

                vbox:
                    ypos 65
                    style_prefix "check"
                    label _("SKIP")
                    textbutton _("Unseen Text") action Preference("skip", "toggle"):
                        ypos 10
                    textbutton _("After Choices") action Preference("after choices", "toggle"):
                        ypos 5
                    textbutton _("Transitions") action InvertSelected(Preference("transitions", "toggle")):
                        ypos 5

            vbox:
                xpos 50
                #xalign 0.5
                #yalign 0.5
                vbox:
                    style_prefix "radio"
                    label _("ROLLBACK SIDE")
                    textbutton _("Disable") action Preference("rollback side", "disable"):
                        ypos 5
                    textbutton _("Left") action Preference("rollback side", "left")
                    textbutton _("Right") action Preference("rollback side", "right")
                
                vbox:
                    ypos 6
                    style_prefix "radio"
                    label _("WERESEX")
                    textbutton _("On") action SetVariable("persistent.weresex", True):
                        ypos 5
                    textbutton _("Off") action SetVariable("persistent.weresex", False)


            vbox:
                xpos 100

                style_prefix "slider"
                box_wrap False

                vbox: ## audio slider labels

                    pos (0, 0)
                    label _("{color=FFFFFF}MUSIC VOLUME{/color}")
                    spacing 20
                    null height 10
                    label _("{color=FFFFFF}SOUND VOLUME{/color}")
                    null height 10
                    label _("{color=FFFFFF}VOICE VOLUME{/color}") ## need to change this for explicit

                vbox: ## audio sliders
                    pos (0, -260)
                    bar value Preference("music volume") style_prefix "slider"
                    spacing 20
                    null height 5
                    bar value Preference("sound volume") style_prefix "slider"
                    if config.sample_sound:
                        textbutton _("Test") action Play("sound", config.sample_sound)
                    null height 5                    
                    bar value Preference("voice volume") style_prefix "slider"  ## need to change this for explicit
                    if config.sample_voice:
                        textbutton _("Test") action Play("voice", config.sample_voice)
                    if config.has_music or config.has_sound or config.has_voice:
                        #null height gui.pref_spacing
                        textbutton _("Mute All"):
                            action Preference("all mute", "toggle")
                            style "mute_all_button"
                vbox: ## text speed labels
                    pos (0, -250)
                    label _("{color=FFFFFF}TEXT SPEED{/color}")
                    spacing 20
                    null height 10
                    label _("{color=FFFFFF}AUTO-FORWARD TIME{/color}")

                vbox:
                    pos (0, -395)                    
                    bar value Preference("text speed")
                    spacing 20
                    null height 5
                    bar value Preference("auto-forward time")                


style pref_label is gui_label
style pref_label_text is gui_label_text
style pref_vbox is vbox

style radio_label is pref_label
style radio_label_text is pref_label_text
style radio_button is gui_button
style radio_button_text:
    properties gui.button_text_properties("radio_button")
    yoffset -16
style radio_vbox is pref_vbox

style check_label is pref_label
style check_label_text is pref_label_text
style check_button is gui_button
style check_button_text: # is gui_button_text
    properties gui.button_text_properties("check_button")
    yoffset -16
style check_vbox is pref_vbox

style slider_label is pref_label
style slider_label_text is pref_label_text
style slider_slider is gui_slider
style slider_button is gui_button
style slider_button_text is gui_button_text
style slider_pref_vbox is pref_vbox

style mute_all_button is check_button
style mute_all_button_text is check_button_text

$ style.bar.thumb_offset = -500

style pref_label:
    top_margin gui.pref_spacing
    bottom_margin 3

style pref_label_text:
    yalign 1.0

style pref_vbox:
    xsize 338

style radio_vbox:
    spacing gui.pref_button_spacing

style radio_button:
    properties gui.button_properties("radio_button")
    foreground "gui/custom/check_[prefix_]foreground.png"

style radio_button_text:
    properties gui.text_properties("radio_button")

style check_vbox:
    spacing gui.pref_button_spacing

style check_button:
    properties gui.button_properties("check_button")
    foreground "gui/custom/check_[prefix_]foreground.png"    

style check_button_text:
    properties gui.text_properties("check_button")

style slider_slider:
    xsize 525

style slider_button:
    properties gui.button_properties("slider_button")
    yalign 0.5
    left_margin 15

style slider_button_text:
    properties gui.text_properties("slider_button")

style slider_vbox:
    xsize 675



BBN_VN
Newbie
Posts: 16
Joined: Sat Feb 20, 2021 1:33 pm
Contact:

Re: Custom GUI - Button and slider alignment/positioning

#6 Post by BBN_VN »

Woo hoo! Finally got it all sorted out. Thanks everyone for the help. I wound up adding the following to the bar values (just a matter of finding the right place to put the code):

Code: Select all

bar value Preference("sound volume") style_prefix "slider":
                        thumb_offset 12.5
I'd still welcome any feedback on the absolute hash I made of things and if there is a better way to get the results I wanted. Cheers.

HiramTromp
Newbie
Posts: 1
Joined: Tue May 07, 2024 3:24 am
Contact:

Re: Custom GUI - Button and slider alignment/positioning

#7 Post by HiramTromp »

Thank you for the help.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot]