Hi there,
Sorry for the delay. I had to check into the codebase to make sure I wasn’t going to give you erroneous advice.
To make sure you’re getting the manipulators setup, I’ve included some example code below formed from the FileInput’s DeviceUI class.
Important things to note is that the manipulators are returned by value, so that they do not have to have any kind of lifespan – you can create them on the fly. The only important thing is that the manipulator
ID codes mean something coherent to your plugin.
You should certainly be getting different indices in your actionManipulator code.
One thing you are quickly running into is that the Device Layout-UI interface has been implemented only to the minimalist set of operations necessary for internal use.
For example, inside World Machine the interface is used by the File Input and Tiled File Input devices, and also used by the Render Extents manipulation page in the layout view.
Ultimately, I feel like many devices could benefit from exposing graphical manipulation tools, but I ran out of time in the previous major release doing so.
With that in mind… after a double-check of the internal code, the only two manipulator actions that are implemented at the moment are LVM_DRAG and LVM_DOUBLECLICK. These were simply the only parts needed by the internal systems. (LVM_SIMPLE manipulators are essentially those that only receive LVM_DRAG messages).
// critical method implementations
int FileInUIClient::numManipulator() { return 5; };
LV_Manipulator FileInUIClient::getManipulator(int i) {
LV_Manipulator manip;
FileInput *owner = (FileInput*)base_owner;
Rect4F &rq = owner->GetRenderExtents();
// all manipulators are simple and framework-draw-managed (we draw some extras in OnDraw as well)
manip.flags = LVM_FLAG_AUTODRAW | LVM_FLAG_SIMPLE;
switch ( i ) {
case 0: // The main area manipulator
manip.flags = 0;
manip.type = LVM_AREA;
manip.area = rq;
manip.code = 0;
break;
case 1:
manip.type = LVM_POINT; // Low-left corner
manip.point = CoordF(rq.x0, rq.y0);
manip.code = 1;
break;
case 2:
manip.type = LVM_POINT; // Low-right corner
manip.point = CoordF(rq.x1, rq.y0);
manip.code = 2;
break;
case 3:
manip.type = LVM_POINT; // Upper-right corner
manip.point = CoordF(rq.x1, rq.y1);
manip.code = 3;
break;
case 4:
manip.type = LVM_POINT; // Upper-left corner
manip.point = CoordF(rq.x0, rq.y1);
manip.code = 4;
break;
default:
break;
};
return manip;
};
bool FileInUIClient::actionManipulator(int i, LVM_ACTION act, Vector2 wpoint, int flags) {
FileInput *owner = (FileInput*)base_owner;
Rect4F &area = owner->GetRenderExtents();
switch ( i ) {
case 0: // The main area manipulator
if (act == LVM_DBLCLICK) {
owner->RunUI();
return true;
}
else if (act == LVM_DRAG) {
owner->setOrigin(offset);
return true;
}
break;
case 1: // Low-left
area.x0 = wpoint.x;
area.y0 = wpoint.y;
break;
case 2:// Low-right corner
area.x1 = wpoint.x;
area.y0 = wpoint.y;
break;
case 3:// Upper-right corner
area.x1 = wpoint.x;
area.y1 = wpoint.y;
break;
case 4:// Upper-left corner
area.x0 = wpoint.x;
area.y1 = wpoint.y;
default:
break;
};
area.Validate();
offset.x = area.x0; offset.y = area.y0;
owner->setOrigin(offset);
return true;
};
bool FileInUIClient::OnDraw(LV_GUIData &style) {
Rect4F &rq = owner->GetRenderExtents();
glLineWidth(3.0f);
// paint a transparent overlay of file input area
glBegin(GL_QUADS);
glColor4f(0.4f, 0.4f, 0.4f, 0.25f);
glVertex3f(x1,y1, 0.0f);
glVertex3f(x2,y1, 0.0f);
glVertex3f(x2,y2, 0.0f);
glVertex3f(x1,y2, 0.0f);
glEnd();
return true;
};
char* FileInUIClient::getManipulatorHelp(int i) {
if (i == 0)
return "Drag to move the file input extents, or Double-click to edit";
else {
return "Drag manipulator to adjust extents. +SHIFT constrains to square";
}
};