Having implemented support for the mouse wheel to zoom in on a GeUserArea
based plugin in R21, I was surprised that this didn't work when ported to R20.
Apparently the GetInputState(BFM_INPUT_MOUSE, chn, mi)
returns false in R20, while it returns true in R21.
Am I missing something obvious?
Below is the full plugin code (except the necessary icon file):
Main.cpp
// Main.cpp
#include "c4d.h"
#include "MyUserArea.h"
Bool PluginStart(void)
{
ApplicationOutput("Test"_s);
if (!RegisterCommandPlugin(MYCOMMAND_PLUGIN_ID, "Test Cmd-Dlg-UA"_s, 0, AutoBitmap("CmdDlgUA.png"_s), "Test"_s, NewObjClear(MyCommand)))
ApplicationOutput("Test - failed registering CommandData");
return true;
}
void PluginEnd(void)
{
}
Bool PluginMessage(Int32 id, void * data)
{
switch (id) {
case C4DPL_INIT_SYS:
if (!g_resource.Init())
return false;
return true;
case C4DMSG_PRIORITY:
return true;
case C4DPL_BUILDMENU:
break;
case C4DPL_ENDACTIVITY:
return true;
}
return false;
}
MyUserArea.cpp
// MyUserArea.cpp
#include "c4d.h"
#include "lib_clipmap.h"
#include "MyUserArea.h"
// ====================================
// GeUserArea
// ====================================
MyUserArea* g_UserArea = nullptr;
MyUserArea::MyUserArea(void) : mWidth(0), mHeight(0) {}
MyUserArea::~MyUserArea(void) {}
Bool MyUserArea::Init(void)
{
return true;
}
Bool MyUserArea::GetMinSize(Int32& w, Int32& h)
{
w = 100;
h = 100;
return true;
}
void MyUserArea::Sized(Int32 w, Int32 h)
{
mWidth = w;
mHeight = h;
}
Bool MyUserArea::InitValues(void)
{
mWidth = GetWidth();
mHeight = GetHeight();
return true;
}
void MyUserArea::DrawMsg(Int32 x1, Int32 y1, Int32 x2, Int32 y2, const BaseContainer& msg)
{
OffScreenOn();
const Int32 w = GetWidth();
const Int32 h = GetHeight();
const Int32 size = (w < h) ? w : h;
const Int32 halfsize = size / 2;
if (!mClipmap)
return;
mClipmap->Init(w, h, 32);
mClipmap->BeginDraw();
Vector color(64);
mClipmap->SetColor(SAFEINT32(color.x), SAFEINT32(color.y), SAFEINT32(color.z), 255);
mClipmap->FillRect(0, 0, w, h);
// do some more drawing stuff ...
mClipmap->EndDraw();
DrawBitmap(mClipmap->GetBitmap(), 0, 0, w, h, 0, 0, w, h, BMP_ALLOWALPHA);
}
Bool MyUserArea::InputEvent(const BaseContainer& msg)
{
const Int32 dev = msg.GetInt32(BFM_INPUT_DEVICE);
const Int32 chn = msg.GetInt32(BFM_INPUT_CHANNEL);
if (dev == BFM_INPUT_MOUSE)
{
if (chn == BFM_INPUT_MOUSEWHEEL)
{
const Float wheel = msg.GetFloat(BFM_INPUT_VSCROLL) / 120.0;
BaseContainer mi;
if (!GetInputState(BFM_INPUT_MOUSE, chn, mi)) // *** here seems to be the difference between R20 and R21 ***
{
ApplicationOutput("MouseWheel - no input state");
return false;
}
Int32 mx = mi.GetInt32(BFM_INPUT_X);
Int32 my = mi.GetInt32(BFM_INPUT_Y);
Global2Local(&mx, &my);
ApplicationOutput("Mousewheel value @ at x=@, y=@", wheel, mx, my);
return true;
}
}
return false;
}
// ====================================
// GeDialog
// ====================================
MyDialog::MyDialog(void) {}
MyDialog::~MyDialog(void) {}
Bool MyDialog::CreateLayout(void)
{
Bool res = GeDialog::CreateLayout();
GroupBegin(0, BFH_SCALEFIT | BFV_SCALEFIT, 1, 0, ""_s, 0);
GroupBorderSpace(4, 4, 4, 4);
// userarea for drawing
GroupBegin(0, BFH_SCALEFIT | BFV_SCALEFIT, 1, 0, String(), 0);
C4DGadget* ua = AddUserArea(IDC_USERAREA, BFH_SCALEFIT | BFV_SCALEFIT, 400, 400);
if (ua)
AttachUserArea(mUserArea, IDC_USERAREA);
GroupEnd();
GroupEnd();
return res;
}
Bool MyDialog::InitValues(void)
{
if (!GeDialog::InitValues())
return false;
return true;
}
void MyDialog::DestroyWindow(void)
{
if (g_UserArea)
g_UserArea = nullptr;
}
// ====================================
// CommandData
// ====================================
Bool MyCommand::Execute(BaseDocument* doc, GeDialog* parentManager)
{
if (!dlg.IsOpen())
{
dlg.Open(DLG_TYPE::ASYNC, MYCOMMAND_PLUGIN_ID, -1, -1, 0, 0, 0);
g_UserArea = &dlg.mUserArea;
}
else
{
if (g_UserArea)
g_UserArea->Redraw();
}
return true;
}
Bool MyCommand::RestoreLayout(void* secret)
{
Int32 subid = ((RestoreLayoutSecret*)secret)->subid;
if (subid == 0)
{
Bool ret = dlg.RestoreLayout(MYCOMMAND_PLUGIN_ID, subid, secret);
g_UserArea = &dlg.mUserArea;
return ret;
}
return false;
}
MyUserArea.h
// MyUserArea.h
#include "c4d.h"
#include "lib_clipmap.h"
#include "PluginIDs.h"
// ====================================
// GeUserArea
// ====================================
class MyUserArea : public GeUserArea
{
INSTANCEOF(MyUserArea, GeUserArea)
public:
MyUserArea(void);
virtual ~MyUserArea();
virtual Bool Init(void);
virtual Bool GetMinSize(Int32& w, Int32& h);
virtual void Sized(Int32 w, Int32 h);
virtual Bool InitValues(void);
virtual void DrawMsg(Int32 x1, Int32 y1, Int32 x2, Int32 y2, const BaseContainer& msg);
virtual Bool InputEvent(const BaseContainer& msg);
private:
Int32 mWidth;
Int32 mHeight;
AutoAlloc<GeClipMap> mClipmap;
};
// ====================================
// GeDialog
// ====================================
class MyDialog : public GeDialog
{
public:
MyDialog(void);
virtual ~MyDialog(void);
virtual Bool CreateLayout(void);
virtual Bool InitValues(void);
virtual void DestroyWindow(void);
MyUserArea mUserArea;
};
// ====================================
// CommandData
// ====================================
class MyCommand : public CommandData
{
INSTANCEOF(MyCommand, CommandData)
public
virtual Bool Execute(BaseDocument* doc, GeDialog* parentManager);
virtual Bool RestoreLayout(void* secret);
MyDialog dlg;
};
PluginIDs.h
// PluginIDs.h
// Dummy IDs - for demonstration purposes only
#define MYCOMMAND_PLUGIN_ID 1000000
// gadget IDs
#define IDC_USERAREA 50000
Note that for R20 one need to remove the 2nd parameter of the CommandData::Execute
method!
I am using R20.059 and R21.207