foone / 3DMMForever

A modernized version of the Microsoft 3D Movie Maker release
MIT License
537 stars 24 forks source link

[feature] Minor annoyance: Allow an escape key binding on popups #14

Open davidrenne opened 2 years ago

davidrenne commented 2 years ago

Instead of having to click the red close button, allow for an escape key to do the same thing.

willbr commented 1 year ago

hotkeys are defined in utest.rc

https://github.com/foone/3DMMForever/blob/79b301091175459dd39ec53bbb8a711248e969c6/src/studio/utest.rc#L58-L79

willbr commented 1 year ago

Browsers and Easels are implimented in Chunky Script. This could prove a tad complicated.

We might need to create a new event that we can add a handler for in the Chunky Script.

jayrod246 commented 1 year ago

You might also get away with just handling it with the command handler ESL and the various browser classes. I believe there is a base browser class? And they are what get instantiated by those scripts I think.

Edit: Or have the escape key send a cancel button command.

willbr commented 1 year ago

I'm not sure how to find which Browser to dispatch the message to.

If I hardcode it to just one kidCameraGlass it works.

/***************************************************************************
    Escape Key
***************************************************************************/
bool Studio::FCmdEscapeKey(PCMD pcmd)
{
    PKidspaceGraphicObject pgok = pvNil;

    AssertThis(0);
    AssertVarMem(pcmd);

    printf("Studio::FCmdEscapeKey\n");

    pgok = (PKidspaceGraphicObject)((APP *)vpappb)->Pkwa()->PgobFromHid(kidCameraGlass);

    if (pgok != pvNil)
    {
        vpcex->EnqueueCid(cidBrowserCancel, pgok, pvNil, kidBrowserCancel, 0,0,0);
    }

    return fTrue;
}
willbr commented 1 year ago

The same works for Easels.

It feels like a bit of a bodge, but we could iterate over the handler id's.

And, if it has a graphic object, post the cancel message.

/***************************************************************************
    Escape Key
***************************************************************************/
bool Studio::FCmdEscapeKey(PCMD pcmd)
{
    PKidspaceGraphicObject pgok = pvNil;

    AssertThis(0);
    AssertVarMem(pcmd);

    printf("Studio::FCmdEscapeKey\n");

    pgok = (PKidspaceGraphicObject)((APP *)vpappb)->Pkwa()->PgobFromHid(kidCostGlass);

    if (pgok != pvNil)
    {
        // vpcex->EnqueueCid(cidBrowserCancel, pgok, pvNil, kidBrowserCancel, 0,0,0);
        vpcex->EnqueueCid(cidEaselCancel, pgok, pvNil, 0, 0,0,0);
    }

    return fTrue;
}
willbr commented 1 year ago

One edge case I've seen noted in the Chunky scripts is the Sound Recorder.

You've got an Easel open over a Browser.

jayrod246 commented 1 year ago

Have it send without a target, pvNil. The browser/easel should pick it up since the command accepts fcmmNobody.

But still need to figure out edge cases where there would be multiple browsers or easels open at a time.

willbr commented 1 year ago

Do you mean like this?

    vpcex->EnqueueCid(cidClicked, pvNil, pvNil, 0,0,0,0);
    vpcex->EnqueueCid(cidBrowserCancel, pvNil,pvNil, kidBrowserCancel, 0,0,0);

That didn't work for me.

I assumed it was because I had to pass the GOK object.

browser.cht

CLICK_SCRIPT("Browser cancel clicked")
    EnqueueCid(cidBrowserCancel, GidParGob(GidParThis()), GidThis(), 0, 0, 0);
ENDCHUNK

Is fcmmNobody for Handlers that handle all events?

jayrod246 commented 1 year ago

Ah, so the browsers never receive the commands because they are never being added the Command Execution list. So the only way currently they are able to handle them is if you pass the GOK object.

So you need to do something similar like this in the browser constructor/init: https://github.com/foone/3DMMForever/blob/79b301091175459dd39ec53bbb8a711248e969c6/src/studio/studio.cpp#L261-L262

And the browsers have their own Command Handler Level. This constant is defined but never used: https://github.com/foone/3DMMForever/blob/79b301091175459dd39ec53bbb8a711248e969c6/inc/browser.h#L37

I got an opportunity to play around here and was able to get them to handle the command, but it turns out you can "cancel" those roll call views (the actor/prop selection views on the sides) 😂

So a little more work to be done but definitely getting somewhere lol.

jayrod246 commented 1 year ago

Is fcmmNobody for Handlers that handle all events?

It means it handles those events that have no target, specifically pvNil. And fcmmOthers means it handles those that do have a target, but it isn't us.

https://github.com/foone/3DMMForever/blob/79b301091175459dd39ec53bbb8a711248e969c6/kauai/src/cmd.h#L87-L94

To handle all events you can use kgrfcmmAll, which is what the helper ON_CID_ALL does: https://github.com/foone/3DMMForever/blob/79b301091175459dd39ec53bbb8a711248e969c6/kauai/src/cmd.h#L116-L119