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);
        
        
        }
    

Log in to reply