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