The-NodeBox-Generator/NBEditor.cpp
rubenwardy 66f008da28 Start the properties sidebar
Currently works with x,y,z / x2,y2,z2 properties,
need to add nodebox name property.
2014-02-11 20:03:02 +00:00

453 lines
13 KiB
C++

#include "NBEditor.h"
// The gui id numbers for this mode
// NOTE: the maximum that can be here is 20
// see in MenuState.h to raise limit
enum ENB_GUI{
ENB_GUI_MAIN_LISTBOX = GUI_SIDEBAR + 1,
ENB_GUI_MAIN_MSG = GUI_SIDEBAR + 2,
ENB_GUI_PROP = GUI_SIDEBAR + 3,
ENB_GUI_PROP_X1 = GUI_SIDEBAR + 4,
ENB_GUI_PROP_Y1 = GUI_SIDEBAR + 5,
ENB_GUI_PROP_Z1 = GUI_SIDEBAR + 6,
ENB_GUI_PROP_X2 = GUI_SIDEBAR + 7,
ENB_GUI_PROP_Y2 = GUI_SIDEBAR + 8,
ENB_GUI_PROP_Z2 = GUI_SIDEBAR + 9,
ENB_GUI_PROP_NAME = GUI_SIDEBAR + 19,
ENB_GUI_PROP_UPDATE = GUI_SIDEBAR + 11,
ENB_GUI_PROP_REVERT = GUI_SIDEBAR + 12
};
NBEditor::NBEditor(EditorState* st)
:EditorMode(st),current(-1),prop_needs_update(false)
{
// Top Window
cdrs[0] = CDR(EVIEW_XZ,CDR_X_P);
cdrs[1] = CDR(EVIEW_XZ,CDR_X_N);
cdrs[2] = CDR(EVIEW_XZ,CDR_Z_P);
cdrs[3] = CDR(EVIEW_XZ,CDR_Z_N);
cdrs[4] = CDR(EVIEW_XZ,CDR_XZ);
// Front window
cdrs[5] = CDR(EVIEW_XY,CDR_X_P);
cdrs[6] = CDR(EVIEW_XY,CDR_X_N);
cdrs[7] = CDR(EVIEW_XY,CDR_Y_P);
cdrs[8] = CDR(EVIEW_XY,CDR_Y_N);
cdrs[9] = CDR(EVIEW_XY,CDR_XY);
// Side window
cdrs[10] = CDR(EVIEW_ZY,CDR_Y_P);
cdrs[11] = CDR(EVIEW_ZY,CDR_Y_N);
cdrs[12] = CDR(EVIEW_ZY,CDR_Z_P);
cdrs[13] = CDR(EVIEW_ZY,CDR_Z_N);
cdrs[14] = CDR(EVIEW_ZY,CDR_ZY);
// Snappers
for (int i=0;i<17;i++){
snappers[i]=NULL;
}
printf("Making 16 pixel snap grid: \n");
for (int a=-(NODE_RES/2);a<(NODE_RES/2)+1;a++){
snappers[a+(NODE_RES/2)] = a*((float)1/(float)NODE_RES);
printf(">> %f\n",snappers[a+8]);
}
}
void addBox(IGUIElement* parent,IGUIEnvironment* guienv, vector2di pos,int index,const wchar_t* label){
guienv->addStaticText(label,rect<s32>(pos.X,pos.Y,pos.X+20,pos.Y+20),false,true,parent)->setNotClipped(true);
guienv->addEditBox(L"",rect<s32>(pos.X+15,pos.Y,pos.X+200,pos.Y+20),true,parent,index)->setNotClipped(true);
}
void addXYZ(IGUIElement* parent,IGUIEnvironment* guienv, vector2di pos,int startIndex){
addBox(parent,guienv,vector2di(pos.X,pos.Y),startIndex,L"X"); // 0,0
addBox(parent,guienv,vector2di(pos.X,pos.Y+30),startIndex+1,L"Y"); // 80, 0
addBox(parent,guienv,vector2di(pos.X,pos.Y+60),startIndex+2,L"Z"); // 160, 0
}
void NBEditor::load(){
IGUIStaticText* sidebar = GetState()->Menu()->GetSideBar();
IGUIEnvironment* guienv = GetState()->GetDevice()->getGUIEnvironment();
if (sidebar){
sidebar->setText(L"Node Box Tool");
IGUIStaticText* t = guienv->addStaticText(L"No node selected",rect<s32>(20,30,140,100),false,true,sidebar,ENB_GUI_MAIN_MSG);
IGUIListBox* lb = guienv->addListBox(rect<s32>(20,30,230,128),sidebar,ENB_GUI_MAIN_LISTBOX,true);
if (lb){
lb->setVisible(false);
IGUIButton* b = guienv->addButton(rect<s32>(0,100,50,125),lb,GUI_PROJ_NEW_BOX,L"+",L"Add a node box");
IGUIButton* c = guienv->addButton(rect<s32>(60,100,110,125),lb,GUI_PROJ_DELETE_BOX,L"-",L"Delete node box");
b->setNotClipped(true);
c->setNotClipped(true);
}
t = guienv->addStaticText(L"Properties",rect<s32>(0,170,120,190),false,true,sidebar,ENB_GUI_PROP);
t->setVisible(false);
addXYZ(t,guienv,vector2di(10,30),ENB_GUI_PROP_X1);
addXYZ(t,guienv,vector2di(10,130),ENB_GUI_PROP_X2); // 60
guienv->addButton(rect<s32>(30,230,100,260),t,ENB_GUI_PROP_UPDATE,L"Update",L"")->setNotClipped(true);
guienv->addButton(rect<s32>(110,230,180,260),t,ENB_GUI_PROP_REVERT,L"Revert",L"")->setNotClipped(true);
}
load_ui();
}
void fillTB(IGUIElement* sidebar,int parentId,int id,float value){
IGUIElement* e = sidebar->getElementFromId(parentId)->getElementFromId(id);
if (e){
IGUIEditBox* b = static_cast<IGUIEditBox*>(e);
if (!b)
return;
b->setText(stringw(value).c_str());
}
}
void NBEditor::load_ui(){
IGUIStaticText* sidebar = GetState()->Menu()->GetSideBar();
if (!sidebar)
return;
IGUIEnvironment* guienv = GetState()->GetDevice()->getGUIEnvironment();
Node* node = GetState()->project->GetCurrentNode();
if (!node){
sidebar->getElementFromId(ENB_GUI_MAIN_MSG)->setVisible(true);
sidebar->getElementFromId(ENB_GUI_MAIN_LISTBOX)->setVisible(false);
sidebar->getElementFromId(ENB_GUI_PROP)->setVisible(false);
}else{
IGUIListBox* lb = (IGUIListBox*) sidebar->getElementFromId(ENB_GUI_MAIN_LISTBOX);
sidebar->getElementFromId(ENB_GUI_MAIN_MSG)->setVisible(false);
sidebar->getElementFromId(ENB_GUI_PROP)->setVisible(false);
if (lb){
lb->clear();
lb->setVisible(true);
for (int i = 0;i<NODEB_MAX;i++){
NodeBox* box = node->GetNodeBox(i);
if (box){
size_t origsize = strlen(box->name.c_str()) + 1;
static wchar_t wcstring[1024];
mbstowcs(wcstring, box->name.c_str(), origsize);
wcscat(wcstring, L"");
lb->addItem(wcstring);
}
}
lb->setSelected(lb->getListItem(node->GetId()));
}
fillProperties();
}
}
void NBEditor::fillProperties(){
IGUIStaticText* sidebar = GetState()->Menu()->GetSideBar();
if (!sidebar)
return;
Node* node = GetState()->project->GetCurrentNode();
if (!node)
return;
NodeBox* nb = node->GetCurrentNodeBox();
if (!nb)
return;
sidebar->getElementFromId(ENB_GUI_PROP)->setVisible(true);
fillTB(sidebar,ENB_GUI_PROP,ENB_GUI_PROP_X1,nb->one.X);
fillTB(sidebar,ENB_GUI_PROP,ENB_GUI_PROP_Y1,nb->one.Y);
fillTB(sidebar,ENB_GUI_PROP,ENB_GUI_PROP_Z1,nb->one.Z);
fillTB(sidebar,ENB_GUI_PROP,ENB_GUI_PROP_X2,nb->two.X);
fillTB(sidebar,ENB_GUI_PROP,ENB_GUI_PROP_Y2,nb->two.Y);
fillTB(sidebar,ENB_GUI_PROP,ENB_GUI_PROP_Z2,nb->two.Z);
}
void NBEditor::unload(){}
void NBEditor::update(double dtime){
}
void NBEditor::draw(irr::video::IVideoDriver* driver){
if (wasmd && !GetState()->mousedown){
current = -1;
}
for (int i=0;i<15;i++){
if (cdrs[i].visible){
rect<s32> drawarea = rect<s32>(cdrs[i].position.X-5,cdrs[i].position.Y-5,cdrs[i].position.X+5,cdrs[i].position.Y+5);
if (!wasmd && GetState()->mousedown && drawarea.isPointInside(GetState()->mouse_position)){
current = i;
}
SColor color = SColor(255,255,255,255);
if (current == i){
color = SColor(255,0,0,255);
}else if (GetState()->keys[KEY_LCONTROL]==EKS_DOWN){
color = SColor(255,255,255,0);
}
driver->draw2DImage(
driver->getTexture("media/gui_scale.png"),
drawarea.UpperLeftCorner,
rect<s32>(0,0,10,10),NULL,color,true
);
cdrs[i].visible = false;
}
}
if (!wasmd && GetState()->mousedown){
wasmd = true;
}else if (wasmd && !GetState()->mousedown){
wasmd = false;
}
}
void NBEditor::viewportTick(VIEWPORT window,irr::video::IVideoDriver* driver,rect<s32> offset){
for (int i=0;i<15;i++){
if (cdrs[i].window == window){
cdrs[i].update(this,(current == i),offset);
}
}
}
void CDR::update(NBEditor* editor,bool drag,rect<s32> offset){
if (!editor->GetState()->project){
printf("Project for NBEditor::updatePoint() not found!\n");
return;
}
if (!editor->GetState()->Settings()->getSettingAsBool("always_show_position_handle")){
if (editor->GetState()->keys[KEY_LSHIFT]==EKS_UP){
if (type == CDR_XY || type == CDR_XZ || type == CDR_ZY){
return;
}
}else{
if (!(type == CDR_XY || type == CDR_XZ || type == CDR_ZY)){
return;
}
}
}
Node* node = editor->GetState()->project->GetCurrentNode();
if (!node)
return;
NodeBox* box = node->GetCurrentNodeBox();
if (!box)
return;
if (drag){
// get mouse position
position2di target = editor->GetState()->mouse_position;
target.X -= 5;
target.Y -= 5;
target -= offset.UpperLeftCorner;
// get the ray
line3d<irr::f32> ray = editor->GetState()->GetDevice()->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(target,editor->GetState()->GetDevice()->getSceneManager()->getActiveCamera());
// contains the output values
vector3df wpos = vector3df(0,0,0); // the collision position
#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8
const ISceneNode* tmpNode; // not needed, but required for function
#else
ISceneNode* tmpNode; // not needed, but required for function
#endif
triangle3df tmpTri; // not needed, but required for function
// Execute ray
editor->GetState()->GetDevice()->getSceneManager()->getSceneCollisionManager()->getCollisionPoint(ray,editor->GetState()->plane_tri,wpos,tmpTri,tmpNode);
// Snapping
wpos -= vector3df(node->getPosition().X,node->getPosition().Y,node->getPosition().Z);
if (editor->GetState()->Settings()->getSettingAsBool("snapping")==true){
for (int i=0;i<15;i++){
if (wpos.X > editor->snappers[i]-0.0313 && wpos.X < editor->snappers[i]+0.0313){
wpos.X = editor->snappers[i];
}
if (wpos.Y > editor->snappers[i]-0.0313 && wpos.Y < editor->snappers[i]+0.0313){
wpos.Y = editor->snappers[i];
}
if (wpos.Z > editor->snappers[i]-0.0313 && wpos.Z < editor->snappers[i]+0.0313){
wpos.Z = editor->snappers[i];
}
}
}
// Do node limiting
if (editor->GetState()->Settings()->getSettingAsBool("limiting")==true){
// X Axis
if (wpos.X < -0.5)
wpos.X = -0.5;
else if (wpos.X > 0.5)
wpos.X = 0.5;
// Y Axis
if (wpos.Y < -0.5)
wpos.Y = -0.5;
else if (wpos.Y > 0.5)
wpos.Y = 0.5;
// Z Axis
if (wpos.Z < -0.5)
wpos.Z = -0.5;
else if (wpos.Z > 0.5)
wpos.Z = 0.5;
}
// Call required function
if (type < CDR_XZ){
box->resizeNodeBoxFace(editor->GetState(),type,wpos,editor->GetState()->keys[KEY_LCONTROL]==EKS_DOWN);
}else{
box->moveNodeBox(editor->GetState(),type,wpos);
}
node->remesh();
editor->triggerCDRmoved();
}
vector3df pos;
vector3df center = box->GetCenter();
switch (type){
case CDR_X_P:
pos = center;
pos.X = box->two.X;
break;
case CDR_X_N:
pos = center;
pos.X = box->one.X;
break;
case CDR_Y_P:
pos = center;
pos.Y = box->two.Y;
break;
case CDR_Y_N:
pos = center;
pos.Y = box->one.Y;
break;
case CDR_Z_P:
pos = center;
pos.Z = box->two.Z;
break;
case CDR_Z_N:
pos = center;
pos.Z = box->one.Z;
break;
case CDR_XZ:
pos = center;
break;
case CDR_XY:
pos = center;
break;
case CDR_ZY:
pos = center;
break;
}
pos.X+=node->getPosition().X;
pos.Y+=node->getPosition().Y;
pos.Z+=node->getPosition().Z;
#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8
vector2d<irr::s32> cpos = editor->GetState()->GetDevice()->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(pos,editor->GetState()->GetDevice()->getSceneManager()->getActiveCamera());
#else
vector2d<irr::s32> cpos = editor->GetState()->GetDevice()->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(pos,editor->GetState()->GetDevice()->getSceneManager()->getActiveCamera(),true);
#endif
position = cpos += offset.UpperLeftCorner;
visible = true;
return;
}
bool NBEditor::OnEvent(const irr::SEvent &event){
if (event.EventType == EET_GUI_EVENT){
if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED){
switch (event.GUIEvent.Caller->getID()){
case GUI_PROJ_NEW_BOX:
{
Node* node = GetState()->project->GetCurrentNode();
if (node){
printf("Clicked add nb!\n");
node->addNodeBox();
load_ui();
}
}
break;
case GUI_PROJ_DELETE_BOX:
{
Node* node = GetState()->project->GetCurrentNode();
IGUIListBox* lb = (IGUIListBox*) GetState()->Menu()->GetSideBar()->getElementFromId(ENB_GUI_MAIN_LISTBOX);
if (node && node->GetNodeBox(lb->getSelected())){
printf("Clicked delete nb!\n");
node->deleteNodebox(lb->getSelected());
load_ui();
}
}
break;
case ENB_GUI_PROP_REVERT:
{
fillProperties();
}
break;
case ENB_GUI_PROP_UPDATE:
{
IGUIElement* prop = GetState()->Menu()->GetSideBar()->getElementFromId(ENB_GUI_PROP);
if (!prop)
return false;
Node* node = GetState()->project->GetCurrentNode();
if (!node)
return false;
NodeBox* nb = node->GetCurrentNodeBox();
if (!nb)
return false;
try{
nb->one.X = wcstod(prop->getElementFromId(ENB_GUI_PROP_X1)->getText(),NULL);
nb->one.Y = wcstod(prop->getElementFromId(ENB_GUI_PROP_Y1)->getText(),NULL);
nb->one.Z = wcstod(prop->getElementFromId(ENB_GUI_PROP_Z1)->getText(),NULL);
nb->two.X = wcstod(prop->getElementFromId(ENB_GUI_PROP_X2)->getText(),NULL);
nb->two.Y = wcstod(prop->getElementFromId(ENB_GUI_PROP_Y2)->getText(),NULL);
nb->two.Z = wcstod(prop->getElementFromId(ENB_GUI_PROP_Z2)->getText(),NULL);
node->remesh();
}catch(void* e){
GetState()->GetDevice()->getGUIEnvironment()->addMessageBox(L"Update failed",L"Please check that the properties contain only numbers.");
}
}
break;
}
}else if (event.GUIEvent.EventType == EGET_LISTBOX_CHANGED){
Node* node = GetState()->project->GetCurrentNode();
IGUIListBox* lb = (IGUIListBox*) GetState()->Menu()->GetSideBar()->getElementFromId(ENB_GUI_MAIN_LISTBOX);
if (node && lb && node->GetNodeBox(lb->getSelected())){
node->select(lb->getSelected());
load_ui();
}
}
}
return false;
}