mirror of
https://github.com/minetest/irrlicht.git
synced 2024-12-29 09:27:31 +01:00
359 lines
10 KiB
C++
359 lines
10 KiB
C++
|
|
||
|
#include "CGUIEditWindow.h"
|
||
|
#include "IGUISkin.h"
|
||
|
#include "IGUIEnvironment.h"
|
||
|
#include "IGUIElementFactory.h"
|
||
|
#include "IAttributes.h"
|
||
|
#include "IGUIFont.h"
|
||
|
#include "IGUITabControl.h"
|
||
|
#include "IGUITreeView.h"
|
||
|
#include "CGUIEditWorkspace.h"
|
||
|
|
||
|
using namespace irr;
|
||
|
using namespace gui;
|
||
|
|
||
|
//! constructor
|
||
|
CGUIEditWindow::CGUIEditWindow(IGUIEnvironment* environment, core::rect<s32> rectangle, IGUIElement *parent)
|
||
|
: IGUIWindow(environment, parent, -1, rectangle),
|
||
|
Dragging(false), IsDraggable(true), Resizing(false), SelectedElement(0),
|
||
|
AttribEditor(0), OptionEditor(0), EnvEditor(0)
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
setDebugName("CGUIEditWindow");
|
||
|
#endif
|
||
|
|
||
|
// we can't tab out of this window
|
||
|
setTabGroup(true);
|
||
|
// we can ctrl+tab to it
|
||
|
setTabStop(true);
|
||
|
// the tab order number is auto-assigned
|
||
|
setTabOrder(-1);
|
||
|
|
||
|
// set window text
|
||
|
setText(L"GUI Editor");
|
||
|
|
||
|
// return if we have no skin.
|
||
|
IGUISkin *skin = environment->getSkin();
|
||
|
if (!skin)
|
||
|
return;
|
||
|
|
||
|
core::rect<s32> dlgRect(50,50,250,500);
|
||
|
setRelativePosition(dlgRect);
|
||
|
setMinSize(core::dimension2du(200,200));
|
||
|
|
||
|
s32 th = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
|
||
|
IGUITabControl *TabControl = environment->addTabControl(core::rect<s32>(1,th+5,dlgRect.getWidth()-1,dlgRect.getHeight()-1), this, false, true);
|
||
|
TabControl->setSubElement(true);
|
||
|
TabControl->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||
|
|
||
|
//TabControl->addTab(L"Tools");
|
||
|
//L"Texture Cache Browser"
|
||
|
//L"Font Browser"
|
||
|
//L"Font Generator"
|
||
|
//L"Sprite Editor"
|
||
|
//Environment->addGUIElement("textureCacheBrowser", this);
|
||
|
|
||
|
IGUITab* EditorTab = TabControl->addTab(L"Editor");
|
||
|
OptionEditor = (CGUIAttributeEditor*) environment->addGUIElement("attributeEditor", EditorTab);
|
||
|
OptionEditor->grab();
|
||
|
OptionEditor->setID(EGUIEDCE_OPTION_EDITOR);
|
||
|
OptionEditor->setRelativePositionProportional(core::rect<f32>(0.0f, 0.0f, 1.0f, 1.0f));
|
||
|
OptionEditor->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||
|
|
||
|
if (Parent && Parent->getParent() == Environment->getRootGUIElement())
|
||
|
{
|
||
|
IGUITab* EnvTab = TabControl->addTab(L"Env");
|
||
|
EnvEditor = (CGUIAttributeEditor*) environment->addGUIElement("attributeEditor", EnvTab);
|
||
|
EnvEditor->grab();
|
||
|
EnvEditor->setID(EGUIEDCE_ENV_EDITOR);
|
||
|
EnvEditor->setRelativePositionProportional(core::rect<f32>(0.0f, 0.0f, 1.0f, 1.0f));
|
||
|
EnvEditor->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||
|
}
|
||
|
IGUITab* ElementTab = TabControl->addTab(L"Element");
|
||
|
|
||
|
AttribEditor = (CGUIAttributeEditor*) environment->addGUIElement("attributeEditor", ElementTab);
|
||
|
AttribEditor->grab();
|
||
|
AttribEditor->setID(EGUIEDCE_ATTRIB_EDITOR);
|
||
|
AttribEditor->setRelativePositionProportional(core::rect<f32>(0.0f, 0.0f, 1.0f, 1.0f));
|
||
|
AttribEditor->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||
|
|
||
|
IGUITab* TreeTab = TabControl->addTab(L"Tree");
|
||
|
TreeView = environment->addTreeView(core::rect<s32>(0,0,0,0), TreeTab);
|
||
|
TreeView->setRelativePositionProportional(core::rect<f32>(0.0f, 0.0f, 1.0f, 1.0f));
|
||
|
TreeView->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||
|
IGUITreeViewNode* treenode = TreeView->getRoot();
|
||
|
//treenode->addChildFront(L"Elements");
|
||
|
|
||
|
ResizeButton = environment->addButton(core::rect<s32>(dlgRect.getWidth()-(th+1),dlgRect.getHeight()-(th+1),dlgRect.getWidth()-1,dlgRect.getHeight()-1), this);
|
||
|
ResizeButton->setDrawBorder(false);
|
||
|
ResizeButton->setEnabled(false);
|
||
|
ResizeButton->setSpriteBank(skin->getSpriteBank());
|
||
|
ResizeButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_RESIZE), skin->getColor(EGDC_WINDOW_SYMBOL));
|
||
|
ResizeButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_RESIZE), skin->getColor(EGDC_WINDOW_SYMBOL));
|
||
|
ResizeButton->grab();
|
||
|
ResizeButton->setSubElement(true);
|
||
|
ResizeButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT);
|
||
|
|
||
|
updateTree();
|
||
|
}
|
||
|
|
||
|
|
||
|
//! destructor
|
||
|
CGUIEditWindow::~CGUIEditWindow()
|
||
|
{
|
||
|
// drop everything
|
||
|
if (AttribEditor)
|
||
|
AttribEditor->drop();
|
||
|
if (EnvEditor)
|
||
|
EnvEditor->drop();
|
||
|
if (OptionEditor)
|
||
|
OptionEditor->drop();
|
||
|
if (ResizeButton)
|
||
|
ResizeButton->drop();
|
||
|
}
|
||
|
|
||
|
IGUITreeView* CGUIEditWindow::getTreeView() const
|
||
|
{
|
||
|
return TreeView;
|
||
|
}
|
||
|
CGUIAttributeEditor* CGUIEditWindow::getEnvironmentEditor() const
|
||
|
{
|
||
|
return EnvEditor;
|
||
|
}
|
||
|
|
||
|
CGUIAttributeEditor* CGUIEditWindow::getAttributeEditor() const
|
||
|
{
|
||
|
return AttribEditor;
|
||
|
}
|
||
|
|
||
|
CGUIAttributeEditor* CGUIEditWindow::getOptionEditor() const
|
||
|
{
|
||
|
return OptionEditor;
|
||
|
}
|
||
|
|
||
|
IGUITreeViewNode* CGUIEditWindow::getTreeNode(IGUIElement* element, IGUITreeViewNode* searchnode)
|
||
|
{
|
||
|
IGUITreeViewNode* child = searchnode->getFirstChild();
|
||
|
while (child)
|
||
|
{
|
||
|
if (((IGUIElement*) child->getData()) == element)
|
||
|
return child;
|
||
|
|
||
|
if (child->hasChildren())
|
||
|
{
|
||
|
IGUITreeViewNode* foundnode = getTreeNode(element, child);
|
||
|
if (foundnode)
|
||
|
return foundnode;
|
||
|
}
|
||
|
child = child->getNextSibling();
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void CGUIEditWindow::addChildrenToTree(IGUIElement* parentElement, IGUITreeViewNode* treenode)
|
||
|
{
|
||
|
core::stringw name = core::stringw(parentElement->getTypeName());
|
||
|
if (parentElement->getID() != -1)
|
||
|
name += core::stringw(L" [") + core::stringw(parentElement->getID()) + core::stringw(L"]");
|
||
|
|
||
|
IGUITreeViewNode* newnode = treenode->addChildBack(name.c_str());
|
||
|
newnode->setData((void*)parentElement);
|
||
|
core::list<IGUIElement*> children = parentElement->getChildren();
|
||
|
|
||
|
for (core::list<IGUIElement*>::Iterator i = children.begin(); i != children.end(); i++ )
|
||
|
{
|
||
|
if(core::stringc((*i)->getTypeName()) != "GUIEditor" && !(*i)->isSubElement())
|
||
|
addChildrenToTree(*i, newnode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CGUIEditWindow::updateTree()
|
||
|
{
|
||
|
TreeView->getRoot()->clearChildren();
|
||
|
IGUIElement* root = Environment->getRootGUIElement();
|
||
|
addChildrenToTree(root, TreeView->getRoot());
|
||
|
TreeView->getRoot()->getFirstChild()->setExpanded(true);
|
||
|
}
|
||
|
|
||
|
void CGUIEditWindow::setSelectedElement(IGUIElement *sel)
|
||
|
{
|
||
|
// save changes
|
||
|
AttribEditor->updateAttribs();
|
||
|
IGUITreeViewNode* elementTreeNode = getTreeNode(sel, TreeView->getRoot());
|
||
|
|
||
|
if (elementTreeNode)
|
||
|
{
|
||
|
elementTreeNode->setSelected(true);
|
||
|
while (elementTreeNode)
|
||
|
{
|
||
|
elementTreeNode->setExpanded(true);
|
||
|
elementTreeNode = elementTreeNode->getParent();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
io::IAttributes* Attribs = AttribEditor->getAttribs();
|
||
|
|
||
|
if (SelectedElement && sel != SelectedElement)
|
||
|
{
|
||
|
// deserialize attributes
|
||
|
SelectedElement->deserializeAttributes(Attribs);
|
||
|
}
|
||
|
// clear the attributes list
|
||
|
Attribs->clear();
|
||
|
SelectedElement = sel;
|
||
|
|
||
|
// get the new attributes
|
||
|
if (SelectedElement)
|
||
|
SelectedElement->serializeAttributes(Attribs);
|
||
|
|
||
|
AttribEditor->refreshAttribs();
|
||
|
}
|
||
|
|
||
|
//! draws the element and its children.
|
||
|
//! same code as for a window
|
||
|
void CGUIEditWindow::draw()
|
||
|
{
|
||
|
if (!IsVisible)
|
||
|
return;
|
||
|
|
||
|
IGUISkin* skin = Environment->getSkin();
|
||
|
|
||
|
core::rect<s32> rect = AbsoluteRect;
|
||
|
|
||
|
// draw body fast
|
||
|
rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER),
|
||
|
AbsoluteRect, &AbsoluteClippingRect);
|
||
|
|
||
|
if (Text.size())
|
||
|
{
|
||
|
rect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X);
|
||
|
rect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y);
|
||
|
rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
|
||
|
|
||
|
IGUIFont* font = skin->getFont();
|
||
|
if (font)
|
||
|
font->draw(Text.c_str(), rect, skin->getColor(EGDC_ACTIVE_CAPTION), false, true, &AbsoluteClippingRect);
|
||
|
}
|
||
|
|
||
|
IGUIElement::draw();
|
||
|
}
|
||
|
|
||
|
|
||
|
//! called if an event happened.
|
||
|
bool CGUIEditWindow::OnEvent(const SEvent &event)
|
||
|
{
|
||
|
switch(event.EventType)
|
||
|
{
|
||
|
case EET_GUI_EVENT:
|
||
|
switch(event.GUIEvent.EventType)
|
||
|
{
|
||
|
case EGET_ELEMENT_FOCUS_LOST:
|
||
|
if (event.GUIEvent.Caller == this ||
|
||
|
event.GUIEvent.Caller == ResizeButton)
|
||
|
{
|
||
|
Dragging = false;
|
||
|
Resizing = false;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
case EET_MOUSE_INPUT_EVENT:
|
||
|
switch(event.MouseInput.Event)
|
||
|
{
|
||
|
case EMIE_LMOUSE_PRESSED_DOWN:
|
||
|
{
|
||
|
DragStart.X = event.MouseInput.X;
|
||
|
DragStart.Y = event.MouseInput.Y;
|
||
|
|
||
|
IGUIElement* clickedElement = getElementFromPoint(DragStart);
|
||
|
|
||
|
if (clickedElement == this)
|
||
|
{
|
||
|
Dragging = IsDraggable;
|
||
|
//Environment->setFocus(this);
|
||
|
if (Parent)
|
||
|
Parent->bringToFront(this);
|
||
|
return true;
|
||
|
}
|
||
|
else if (clickedElement == ResizeButton)
|
||
|
{
|
||
|
Resizing = true;
|
||
|
//Environment->setFocus(this);
|
||
|
if (Parent)
|
||
|
Parent->bringToFront(this);
|
||
|
return true;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case EMIE_LMOUSE_LEFT_UP:
|
||
|
if (Dragging || Resizing)
|
||
|
{
|
||
|
Dragging = false;
|
||
|
Resizing = false;
|
||
|
return true;
|
||
|
}
|
||
|
break;
|
||
|
case EMIE_MOUSE_MOVED:
|
||
|
if (Dragging || Resizing)
|
||
|
{
|
||
|
// gui window should not be dragged outside of its parent
|
||
|
if (Parent)
|
||
|
if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
|
||
|
event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
|
||
|
event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
|
||
|
event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)
|
||
|
|
||
|
return true;
|
||
|
core::position2di diff(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y);
|
||
|
if (Dragging)
|
||
|
{
|
||
|
move(diff);
|
||
|
DragStart.X = event.MouseInput.X;
|
||
|
DragStart.Y = event.MouseInput.Y;
|
||
|
}
|
||
|
else if (Resizing)
|
||
|
{
|
||
|
core::position2di dp = RelativeRect.LowerRightCorner + diff;
|
||
|
setRelativePosition(core::rect<s32>(RelativeRect.UpperLeftCorner, dp));
|
||
|
DragStart += dp - RelativeRect.LowerRightCorner + diff;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return Parent ? Parent->OnEvent(event) : false;
|
||
|
}
|
||
|
|
||
|
bool CGUIEditWindow::isDraggable() const
|
||
|
{
|
||
|
return IsDraggable;
|
||
|
}
|
||
|
|
||
|
void CGUIEditWindow::setDraggable(bool draggable)
|
||
|
{
|
||
|
IsDraggable = draggable;
|
||
|
|
||
|
if (Dragging && !IsDraggable)
|
||
|
Dragging = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
// we're supposed to supply these if we're creating an IGUIWindow
|
||
|
// but we don't need them so we'll just return null
|
||
|
|
||
|
//! Returns the rectangle of the drawable area (without border, without titlebar and without scrollbars)
|
||
|
core::rect<s32> CGUIEditWindow::getClientRect() const {return core::recti();}
|
||
|
IGUIButton* CGUIEditWindow::getCloseButton() const {return 0;}
|
||
|
IGUIButton* CGUIEditWindow::getMinimizeButton() const {return 0;}
|
||
|
IGUIButton* CGUIEditWindow::getMaximizeButton() const {return 0;}
|