Menu

#325 Add support for file and text dropping over the application's window

open
nobody
None
5
2022-01-04
2022-01-04
No

With this patch, a new event type is added to Irrlicht: EET_DROP_EVENT. This event represents the action of the user dropping a file over the application's window. The handling of the event was inspired by SDL's, with it being passed to the application in multiple stages:
DROP_START is sent at the beginning of a drop event, and lets the application prepare for the incoming data.
Afterwards an arbitary number of DROP_TEXT or DROP_FILE events are sent (even tho for now only DROP_FILE can have multiple elements passed the same drop action).
When all the elements are sent, DROP_END is then sent to the appplication.
The SDropEvent structure contains the X and Y coordinates relative to the application's window at which the element was dropped, the Text field that can be the text or an absolute file path, depending on the drop type, and last the drop type itself.
To make the device start accepting drop events, the function enableDragDrop has to be called

//! Enables text and files drag and drop support
typedef bool(*drop_callback_function_t)(irr::core::vector2di pos, bool isFile, void* userParameter);
virtual void enableDragDrop(bool enable, drop_callback_function_t dragCheck = NULL, void* userParameter = NULL) = 0;

The enable parameter is self explainatory, with it set to true this ffeature is enabled, with it set to false the feature is disabled.
dragCheck is a pointer to a function of signature bool(irr::core::vector2di pos, bool isFile, void* userParameter) that will be called each time the underlying device recieves an event related to a drag and drop operation being carried out, the pos parameter has the current position of the cursor over the window, isFile is set to true if the object being dragged is a file, otherwise it's text, userParameter is whatever got passed as 3rd parameter to enableDragDrop.
If this function returns true, then that means that at those specific coordinates that specific object can be dropped. If no callback function is passed, then it's assumed that all the window surface is a valid drop target.
A sampe usage could be like this

device->enableDragDrop(true, [](irr::core::vector2di pos, bool isFile, void* param) -> bool {
    auto env = static_cast<irr::IrrlichtDevice*>(param)->getGUIEnvironment();
    if(isFile)
        return false;
    auto elem = env->getRootGUIElement()->getElementFromPoint(pos);
    if(elem && elem != env->getRootGUIElement()) {
        if(elem->hasType(irr::gui::EGUIET_EDIT_BOX) && elem->isEnabled())
            return true;
    }
    return false;
}, device);

Here dropping is enabled, but the callback function returns only true if the currently hovered element is an edit box, thus allowing the drop to be done only over those elements.
Regarding edit boxes, they have been update to support drop events, they'll ignore any drop file event, while will treat a drop text event as if it were text being pasted into them.

Currently in this patch I only adapted my code for the windows implementation as to show how it works, with the other devices being stubbed out, but I already have the respective Mac OS and X11 implementations ready and functional that I've been using in my projects (both of them having the same feature parity as the windows one, so with fine positioning check and the supported elements), but they need a bit of polishing and an "update" to upstream Irrlicht without my other custom things. If needed I can clean them up and add them to the patch as well.

I'd like to know if this could be a welcome patch for upstream irrlicht and, in case, if there could be some things that could be improved in the related api.

1 Attachments

Discussion


Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.