git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6000 dfc29bdd-3216-0410-991c-e03cc46cb475
		
			
				
	
	
		
			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;}
 |