kxgames / glooey

An object-oriented GUI library for pyglet.
MIT License
91 stars 6 forks source link

Size error when text too short #36

Closed Snayff closed 4 years ago

Snayff commented 4 years ago

I am just trying to get to grips with glooey so apologies if I am missing something. I am struggling to manage the positioning of widgets. A simple example below, using the code from here as an example which only works with lots of text.

This works: `text = drawing.lorem_ipsum() label = glooey.Label(text, line_wrap=300) label.custom_alignment = "center"

scroll = WesnothScrollBox() scroll.add(label) gui.add(scroll)`

But if I replace text with text = "test" I get RuntimeError: 'top left' placed the child rectangle outside the parent rectangle. This most likely indicates a bug in 'top_left()'. child: <Rect bottom=-182.0 left=0 width=27.0 height=200.0> parent: <Rect bottom=0 left=0 width=27 height=18>

kalekundert commented 4 years ago

Sorry you're having trouble! I'm pretty sure this is a bug that I fixed in a373ae3c, but that fix didn't make it into the most recent release. I just pushed version 0.2.2 to PyPI, so try pip install --upgrade glooey and let me know if that solves the problem.

Snayff commented 4 years ago

Thanks for checking this out so quickly mate. I'll check it out shortly, when I am back at the pc.

If you don't mind my asking, how would you recommend handling the positioning of widgets? I tried to use Board but I couldn't get it to show. (Could be due to the previous error though)

kalekundert commented 4 years ago

Can you give me an idea of the positioning you want to get, and what you tried? Unfortunately, when things don't show up, there are a lot of potential reasons for that. (It's probably not related to the above error, though; I think that's due to an over-aggressive effort to raise an error instead of having nothing show up---kind of the opposite problem.)

Not really related, but making Board more flexible has been on my todo list for a long time. So let me know if you have any trouble with it. Maybe it'll give me the motivation to make those changes I've been thinking about. :-)

Snayff commented 4 years ago

The pip upgrade failed as it couldn't find version 0.2.2. ERROR: Could not find a version that satisfies the requirement glooey==0.2.2 (from versions: 0.1.0, 0.1.1, 0.1.2, 0.2.0, 0.2.1). Is there a lag time?

I wanted to create a Board the size of my pyglet.window and then put the ScrollBox in the bottom right so I set the size hint of the Board to match the window sizes and then tried to add it with left=window.width - scrollbox.width, bottom=0 but I kept getting an error stating the child was being drawn outside of the parent.

The HBox, VBox and Grid seem great for working with widgets within widgets, but I found them a bit tough to use when talking about the whole window size.

kalekundert commented 4 years ago

Try the pip upgrade again. I didn't actually upload it the first time.

A few quick comments:

Snayff commented 4 years ago

Updated glooey and it ran!

Thanks for the pointers, mate. I am back to the other issue: `window_width, window_height = 1280, 720 board = glooey.Board() board.alignment = "fill" gui.add(board)

from scripts.ui_elements.templates.menu_scroll_box import MenuScrollBox scrollbox = MenuScrollBox() scroll_width, scroll_height = 400, 200 scrollbox.size_hint = scroll_width, scroll_height board.add(scrollbox, right=window_width, bottom=0)

text = "test" label = glooey.Label(text, line_wrap=300) label.custom_alignment = "center"

scroll = MenuScrollBox() scroll.add(label)`

Errors on board.add with RuntimeError: Gui(id=4048) is only 1280x720, but its children are 1280x1099.

Tbh, I am not sure how as to my mind I set the size to 200 high but it ends up 1099px instead. Am I thinking about it incorrectly? (and is there anywhere else to ask this so I can avoid bugging you?)

kalekundert commented 4 years ago

No worries about bugging me! This is really probably the best place to get help, anyway. There are more people watching the various pyglet lists, but I'm not always on them, and I can probably give the best answers when it comes to glooey. And I'm happy to help!

I don't know how it got to 1099px either, so I'll have to take a closer look tonight. But I can point out a few things that might get you in the right direction in the mean time:

Snayff commented 4 years ago

Thanks buddy, I do really appreciate the help.

The issue with referencing the wrong scrollbox was actually only in the code I shared so thankfully I haven't fallen for quite such a rookie error!

Copied all the relevant code here: https://pastebin.com/KQKaKC0k

I tried taking our the images from the scrollbox, at which point I get an error on this line height = self._pane.height**2 / self._pane.child.height for this error AttributeError: 'NoneType' object has no attribute 'height' and still caused by board.add.

With the way that Glooey works so smoothly with the example code I am assuming I am not using it properly - sorry!

kalekundert commented 4 years ago

Ok, I will admit that this confused the heck out of me. There is an actual bug in glooey, and I'll fix it shortly. But there's also a small change you should make to your code (which would happen to sidestep the bug).

The immediate cause of the error is that the scroll box is configured to scale its scroll grip, but it doesn't have a child widget at the time it's attached to the gui, i.e. board.add(scrollbox, ...). This is a problem because getting attached to the gui triggers the scroll box calculate how big its grip should be, but it can't do that calculation if it doesn't know what its content is. The bug is because it attempts to do the calculation anyways and ends up choking on it. The fix is simple: just skip the calculation. It'll get worked out later when something is added to the scroll box.

That said, best practice is to avoid attaching anything to the gui (by which I mean the glooey.Gui widget) until everything is ready to go. The reason is efficiency. Once a widget is attached to the gui, it will have to recalculate a bunch of things every time another widget is attached to the gui. So you can minimize the number of things that need to be calculated by making sure that gui.add(whatever) is the last thing you do. It should also work the way you have it, but this should be a little faster.

With all that in mind, here's a version of your code that works for me (I removed all the images and made all the buttons ugly colors):

#!/usr/bin/env python3

import glooey
import pyglet

class MenuScrollBox(glooey.ScrollBox):
    custom_alignment = 'center'

    class Frame(glooey.Frame):

        class Decoration(glooey.Background):
            custom_color = '#eeeeec'

        class Box(glooey.Bin):
            custom_horz_padding = 2

    class VBar(glooey.VScrollBar):
        custom_scale_grip = True

        class Decoration(glooey.Background):
            custom_vert_padding = 25
            custom_color = 'green'

        class Forward(glooey.Button):
            custom_size_hint = 20, 20
            custom_base_color = 'purple'

        class Backward(glooey.Button):
            custom_size_hint = 20, 20
            custom_base_color = 'purple'

        class Grip(glooey.Button):
            custom_size_hint = 20, 20
            custom_alignment = 'fill'
            custom_base_color = 'orange'

window_width, window_height = 1280, 720
win = pyglet.window.Window(window_width, window_height)
gui = glooey.Gui(win)

board = glooey.Board()
# board.size_hint = window_width, window_height # tried this and fill
board.alignment = "fill"

scrollbox = MenuScrollBox()
scroll_width, scroll_height = 400, 200
scrollbox.size_hint = scroll_width, scroll_height

text = "test"
label = glooey.Label(text, line_wrap=400)
#label = glooey.LoremIpsum(line_wrap=400)
label.alignment = "center"

scrollbox.add(label)
board.add(scrollbox, right=window_width, bottom=0)
gui.add(board)

pyglet.app.run()

Let me know if that fixes it for you!

Snayff commented 4 years ago

Thank you for sending this over mate, it worked straight away! Of course I broke it as soon as I tried to use it.

A bit of a funny result as soon as I add the image for top bar (https://imgur.com/0bZLnVb) - the white background moved to the left and the text overlaps the bar.

And when I added the vertical borders I get glooey.helpers.UsageError: image can't be tiled horizontally because it's narrower than its underlying texture (395 px vs 512 p x). but I think that's a need for me to resize to a power of 2, based on the note, right?

kalekundert commented 4 years ago

I'm not sure what's going on with the top bar, maybe make another issue for that and include the code.

You're right about the power-of-two thing. This is discussed in a little more detail in the documentation here: https://glooey.readthedocs.io/en/latest/especially_useful_widgets.html#background-tile-images