Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DirectOptionMenu's "cancelFrame" doesn't work within a DirectScrolledFrame #658

Closed
ArsThaumaturgis opened this issue May 15, 2019 · 3 comments

Comments

@ArsThaumaturgis
Copy link
Contributor

commented May 15, 2019

Simply put, if a DirectOptionMenu is placed on the canvas of a DirectScrolledFrame, one can no longer click outside of the menu to cancel selection.

Unless, that is, one modifies DirectOptionMenu such that its "cancelFrame" has a relief-setting of "DGG.FLAT" (or perhaps other non-"None" settings, too; I haven't tried them). In this case, it works pretty much as expected, save for the "cancelFrame" then covering the menu, and that the menu can only be cancelled within the DirectScrolledFrame (presumably due to the "cancelFrame" being confined to said frame).

A quick test suggests that the problem can also be solved by having the "cancelFrame" be a direct child of "aspect2d", rather than of the DirectOptionMenu. However, I don't know whether that's a desirable solution. In particular, this results in the "cancelFrame" being accessible from anywhere on the screen, and not confined to the DirectScrolledFrame, and I don't know whether that is desirable behaviour...

A short test-program illustrating this issue:

from direct.gui.DirectGui import DirectOptionMenu, DirectScrolledFrame

from direct.showbase import ShowBase as showBase


class Game(showBase.ShowBase):

    def __init__(self):
        showBase.ShowBase.__init__(self)

        self.accept("escape", self.userExit)

        self.list = DirectScrolledFrame(frameSize = (-0.2, 0.5, -0.5, 0.5),
                                        canvasSize = (-0.2, 0.4, -0.5, 0.5),
                                        pos = (0.5, 0, 0))

        self.menu = DirectOptionMenu(
            scale = 0.1,
            pos = (0, 0, 0),
            items = ["Kittens", "Cats", "Mew"],
            item_pad = (0.5, 0.5),
            popupMarker_pos = (0, 0, 0),
            parent = self.list.getCanvas()
        )

        self.menu2 = DirectOptionMenu(
            scale = 0.1,
            pos = (-0.5, 0, 0),
            items = ["Kittens", "Cats", "Mew"],
            item_pad = (0.5, 0.5),
            popupMarker_pos = (0, 0, 0)
        )

    def itemSelected(self, item):
        print ("Selected:", item)

app = Game()
app.run()

@rdb rdb added the bug label Jul 29, 2019

@rdb

This comment has been minimized.

Copy link
Member

commented Jul 29, 2019

It is getting culled away because it has an empty bounding volume. I'm not sure, however, why it's not getting culled away when it's not in a scrolled frame. However, it seems to be fixed when slapping an OmniBoundingVolume on it.

Though, a good argument could be made that neither the popup menu nor the cancel frame should be clipped by the DirectScrolledFrame, but it's not immediately obvious to me how to make that happen.

@rdb rdb added this to the 1.10.4 milestone Jul 29, 2019

@ArsThaumaturgis

This comment has been minimized.

Copy link
Contributor Author

commented Jul 29, 2019

It is getting culled away because it has an empty bounding volume. I'm not sure, however, why it's not getting culled away when it's not in a scrolled frame. However, it seems to be fixed when slapping an OmniBoundingVolume on it.

Ah, that makes sense (well, aside from it not being clipped outside a scrolled-frame)! Fair enough, then, and I'm glad that it seems to be easy to fix! ^_^

Though, a good argument could be made that neither the popup menu nor the cancel frame should be clipped by the DirectScrolledFrame, but it's not immediately obvious to me how to make that happen.

An alternative--albeit perhaps not a perfect one--is something that I've done in a custom sub-class of mine: If such an option-menu finds itself parented below a scrolled-list canvas, it adjusts the position of the menu, attempting to keep it within the frame. (Although I've only adjusted the vertical position thus far, I think.)

However, if it's preferable that the menu not be clipped at all, then perhaps a better idea might be to unhook the popup menu entirely from the option-menu button, having it be parented below gui-popup. The menu would, of course, still manage it on the logical side, but it should then appear outside of scrolled-lists, I think.

@ArsThaumaturgis

This comment has been minimized.

Copy link
Contributor Author

commented Jul 29, 2019

Minor update: I added an OmniBoundingVolume to the "cancelFrame" object of my DirectOptionMenu sub-class, and it does indeed seem to solve the problem--with the exception that it only seems to work when I click within the canvas of the scrolled-frame.

(It is still a vast improvement, and should hold me until the issue is officially resolved in DirectOptionMenu itself, I think! I report it here mainly as a caveat to it being a fix for the problem.)

In case I'm doing something wrong, I implemented this simply by adding the following line at the end of my sub-class's constructor:
self.cancelFrame.node().setBounds(OmniBoundingVolume())
(With the appropriate import above, of course.)

@rdb rdb closed this in 7ab377f Jul 30, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.