MATPREVIEW drag & drop

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 27/07/2008 at 15:28, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   9.603 
Platform:   Windows  ;   
Language(s) :     C++  ;

---------
Hello,
I am trying to process drag and drop for a certain file type over a MATPREVIEW in a MaterialData-derived plugin material. I have done this with no problem when hosting the preview in a GeDialog, but this example is in the Attribute Manager, and the message-processing does not seem to be working as expected. Specifically, I am checking for filenames when MatPreviewHandleDragnDrop::lType is either DRAGTYPE_BROWSER or DRAGTYPE_FILENAME_OTHER. I can get the info I want all right, but am not clear on a few details:
1. when lType == DRAGTYPE_BROWSER, I have to use GetInputState to figure out if the user has released the mouse or not - checking for BFM_DRAG_FINISHED never returns true. Is this workaround the only way to detect this?
2. when lType == DRAGTYPE_FILENAME_OTHER, BFM_DRAG_FINISHED also never returns true. This is apparently no problem, because it appears that with a MATPREVIEW, BFM_DRAGRECEIVE is only given when the mouse has finally been released. However, I am not clear on what I should set MatPreviewHandleDragnDrop::lReturn to - I assume there must be something indicated here to prevent c4d from always showing the 'Unknown file format!' dialog.
3. in either of the above cases, is there a way to show the copy cursor? I toyed with a few things already but couldn't get it to work. The documentation for MatPreviewHandleDragnDrop is pretty sparse and does not say what should be returned in this scenario, as far as I can find.
I will include below a complete test class which shows the behavior I'm describing. Please let me know if I'm missing something obvious, or if this is just not a completely supported operation.
Thanks much,
JD
 
Mtestmat.h

    
    
    #ifndef _Mtestmat_H_
    
    
    #define _Mtestmat_H_
    
    
    
    
    enum
    
    
    {
    
    
        MTESTMAT_PREVIEW = 1001
    
    
    };
    
    
    
    
    #endif

Mtestmat.res

    
    
    
    
    CONTAINER Mtestmat
    
    
    {
    
    
        NAME Mtestmat;
    
        GROUP
    
    
        {
    
    
            MATPREVIEW MTESTMAT_PREVIEW { MIN_WIDTH 150; MIN_HEIGHT 150; OPEN; }
    
        }
    
    
    }

Mtestmat.str

    
    
    STRINGTABLE Mtestmat
    
    
    {
    
    
        Mtestmat "Mtestmat";
    
    
    }

Mtestmat.cpp

    
    
    #include <c4d.h>
    
    
    #include <lib_browser.h>
    
    
    #include <customgui_matpreview.h>
    
    
    #include <Mtestmat.h>
    
    
    
    
    #define ID_MTESTMAT 100000
    
    
    
    
    class Mtestmat : MaterialData
    
    
    {
    
    
    
    
    private:
    
    
    
    
        AutoAlloc<BaseBitmap> preview;
    
    
        LONG updatecount;
    
    
    
    
        Mtestmat(void)
    
    
        {
    
    
            Filename fn = GeGetPluginPath();
    
    
            fn += "res";
    
    
            fn += "k_scale.tif";
    
    
            preview->Init(fn);
    
    
        }
    
    
    
    
    public:
    
    
    
    
        static NodeData *Alloc(void) 
    
    
        { 
    
            return gNew Mtestmat; 
    
    
        }
    
    
    
    
        void HandleDrop(MatPreviewHandleDragnDrop& dnd) 
    
    
        {
    
    
            const BaseContainer& bc = *(dnd.pDragData);
    
    
    
    
            if (bc.GetId() == BFM_DRAGRECEIVE && !bc.GetLong(BFM_DRAG_LOST))
    
            {
    
    
                String dragstring; 
    
    
    
    
                // c4d drag
    
    
                if (dnd.lType == DRAGTYPE_BROWSER)
    
    
                {
    
    
                    SDKBrowserDragInfo* info = (SDKBrowserDragInfo* )(dnd.pObj);
    
    
    
    
                    if (info->GetItemCount() == 1)
    
    
                    {
    
    
                        // only interested in a single filename
    
    
                        SDKBrowserContentNodeRef nref = info->GetItem(0);
    
                        SDKBrowserContentNode* node = nref;
    
    
                        Filename fn;
    
                        node->GetFilename(fn);
    
    
    
    
                        if (fn.Content() && fn.CheckSuffix("txt"))
    
    
                            dragstring = fn.GetString();
    
    
    
    
                    }
    
    
    
    
                    if (dragstring.Content())
    
    
                        // this prints repeatedly 
    
    
                        GePrint(dragstring + " (polling)"); 
    
    
    
    
                    if (dragstring.Content() && bc.GetLong(BFM_DRAG_FINISHED)) 
    
    
                        // this never prints
    
    
                        GePrint(dragstring + " (c4d - BFM_DRAG_FINISHED)"); 
    
    
    
    
                    // this workaround does the trick...
    
    
                    BaseContainer state;
    
    
                    if (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, state))
    
                        if (dragstring.Content() && state.GetLong(BFM_INPUT_VALUE) == 0) 
    
    
                            GePrint(dragstring + " (c4d - workaround)");
    
      
                    // c4d NEVER shows 'unknown file type' 
    
    
                    // dialog when lType == DRAGTYPE_BROWSER
    
    
                }
    
    
    
    
                // OS drag
    
    
                if (dnd.lType == DRAGTYPE_FILENAME_OTHER)
    
    
                {
    
    
                    Filename fn = *((Filename* )(dnd.pObj));
    
    
    
    
                    if (fn.Content() && fn.CheckSuffix("txt"))
    
    
                        dragstring = fn.GetString(); 
    
    
    
    
                    if (dragstring.Content())
    
    
                        // this prints once after mouse is released so there is no reason 
    
                        // to check for BFM_DRAG_FINISHED, which never returns true anyway
    
    
                        GePrint(dragstring + " (os)"); 
    
    
    
    
      
                    // c4d ALWAYS shows 'unknown file type' 
    
    
                    // dialog when lType == DRAGTYPE_FILENAME_OTHER
    
    
                }
    
    
    
    
                // what should this be? will a correct value prevent
    
    
                // the 'unknown file type' dialog from being shown?
    
    
                dnd.lReturn = (dragstring.Content()) ? 1 : 0 ;
    
    
            } 
    
    
        }
    
    
    
    
        virtual Bool Message(GeListNode* node, LONG type, void* data)
    
        {
    
    
            if (!data) return MaterialData::Message(node, type, data);
    
    
    
    
            MatPreviewGenerateImage* image = 0;
    
    
            MatPreviewObjectInfo* info = 0;
    
    
            MatPreviewHandleDragnDrop* dnd = 0;
    
    
    
    
            switch (type)
    
    
            { 
    
    
            case MSG_UPDATE :
    
    
                updatecount ++;
    
    
                break;
    
    
            case MATPREVIEW_GET_OBJECT_INFO:
    
    
                info = (MatPreviewObjectInfo* ) data;
    
                info->bHandlePreview = TRUE; 
    
    
                info->bNeedsOwnScene = FALSE; 
    
    
                info->bNoStandardScene = FALSE; 
    
    
                info->lFlags = MATPREVIEW_FLAG_HIDE_ROTATION |
    
    
                               MATPREVIEW_FLAG_HIDE_SIZE |
    
    
                               MATPREVIEW_FLAG_HIDE_SCENES | 
    
    
                               MATPREVIEW_FLAG_HIDE_ANIMATE |
    
    
                               MATPREVIEW_FLAG_HIDE_OPEN |
    
    
                               MATPREVIEW_FLAG_HIDE_SCENE_SETTINGS |
    
    
                               MATPREVIEW_FLAG_ALLOW_DRAGNDROP;
    
    
                break;
    
    
            case MATPREVIEW_GENERATE_IMAGE :
    
    
                image = (MatPreviewGenerateImage* )data;
    
    
                preview->ScaleIt(image->pDest, 256, TRUE, TRUE);
    
    
                image->lResult = RAY_OK;
    
    
                break;
    
            case MSG_DESCRIPTION_CHECKDRAGANDDROP :
    
    
                // this never prints
    
    
                GePrint("MSG_DESCRIPTION_CHECKDRAGANDDROP");
    
    
                break;
    
    
            case MATPREVIEW_DRAGNDROP_RECV :
    
    
                dnd = (MatPreviewHandleDragnDrop* )data;
    
    
                HandleDrop(*dnd);
    
    
                break;
    
    
            case MATPREVIEW_GET_PREVIEW_ID:
    
    
                *((LONG* )data) = MTESTMAT_PREVIEW;
    
    
                break;
    
    
            }
    
    
    
    
            return MaterialData::Message(node, type, data); 
    
    
        }
    
    
    
    
        virtual Bool GetDParameter(GeListNode *node, const DescID &id,GeData &t_data,LONG &flags)
    
        {
    
    
            BaseMaterial* basemat = (BaseMaterial* )node; 
    
    
            BaseContainer* bc = basemat->GetDataInstance();
    
    
    
    
            updatecount ++;
    
    
    
    
            switch (id[0].id)
    
    
            {
    
            case MTESTMAT_PREVIEW:
    
    
                return GetDParameterPreview(bc, &t_data, flags, MTESTMAT_PREVIEW, updatecount, basemat);
    
            }
    
    
    
    
            return MaterialData::GetDParameter(node, id, t_data, flags);
    
        }
    
    
    
    
        virtual Bool SetDParameter(GeListNode *node, const DescID &id,const GeData &t_data,LONG &flags)
    
        {
    
    
            BaseMaterial* basemat = (BaseMaterial* )node; 
    
    
            BaseContainer* bc = basemat->GetDataInstance();
    
    
    
    
            switch (id[0].id)
    
    
            {
    
    
            case MTESTMAT_PREVIEW: 
    
    
                return SetDParameterPreview(bc, &t_data, flags, MTESTMAT_PREVIEW);
    
            } 
    
    
    
    
            return MaterialData::SetDParameter(node, id, t_data, flags); 
    
        }
    
    
    
    
    };
    
    
    
    
    Bool RegisterMtestmat(void)
    
    
    {
    
    
        return RegisterMaterialPlugin(ID_MTESTMAT,
    
    
                    "Mtestmat",
    
    
                    PLUGINFLAG_MATERIAL_NO_MATERIALEDITOR,
    
                    Mtestmat::Alloc,
    
    
                    "Mtestmat",
    
    
                    0);
    
    
    }