#include "GUIShaderNode.h" GUIShaderNode::GUIShaderNode(IShaderGraphNode* src) :resizing(false), moving(false), GraphicsNode(src) { skip_mouse = true; size_min = Vec2i(100, 50); size_max = Vec2i(250, 250); header = new GUIPlane(); header->SetPosition(Vec2i(0, 0)); header->SetWidth(120); header->SetHeight(25); header->SetBackColor(Vec4f(0.16f,0.16f,0.16f,1)); header->SetBorderColor(Vec4f(0.016f,0.016f,0.016f,1)); body = new GUIPlane(); body->SetPosition(Vec2i(0, 25)); body->SetWidth(120); body->SetHeight(120); body->SetBackColor(Vec4f(0.25f,0.0f,0.0f,1)); body->SetBorderColor(Vec4f(0.016f,0.016f,0.016f,1)); display = new GUIPicture(); body->AddChild(display); display->SetPosition(Vec2i(2,2)); back = new GUIPlane(); back->SetPosition(Vec2i(0, 0)); back->SetWidth(width); back->SetHeight(height); back->SetBackColor(Vec4f(0.9f,0.25f,0.25f,1)); back->SetBorderColor(Vec4f(0.9f,0.016f,0.016f,1)); mover = new GUIPlane(); mover->SetPosition(Vec2i(115, 140)); mover->SetWidth(10); mover->SetHeight(10); mover->SetBackColor(Vec4f(0.75f,0.75f,0.75f,0.5f)); mover->SetBorderColor(Vec4f(0.016f,0.016f,0.016f,1)); mover->cursor = STR("Size_d1"); header_text = new GUIText(); header->AddChild(header_text); header_text->SetDock(Video::DOCK_FILL); header_text->SetHAlign(HA_CENTER); header_text->SetVAlign(VA_CENTER); header_text->SetText("Invert (1-x)"); header_text->SetBackColor(Vec4f(0.0f,0.0f,0.0f,0.0f)); header_text->SetForeColor(Vec4f(0.8f,0.8f,0.8f,1.0f)); header_text->mouseEnabled = false; mover->Event_MouseDown += NewDelegate(this, &GUIShaderNode::OnBeginResize); mover->Event_MouseUp += NewDelegate(this, &GUIShaderNode::OnEndResize); mover->Event_MouseMove += NewDelegate(this, &GUIShaderNode::OnDoResize); header->Event_MouseDown += NewDelegate(this, &GUIShaderNode::OnHeaderMouseDown); header->Event_MouseUp += NewDelegate(this, &GUIShaderNode::OnHeaderMouseUp); header->Event_MouseMove += NewDelegate(this, &GUIShaderNode::OnHeaderMouseMove); header->Event_MouseClick += NewDelegate(this, &GUIShaderNode::OnHeaderMouseClick); menu = new GUIMenu(true); menu->AddItem("Delete node", false); //AddChild(back); AddChild(body); AddChild(mover); AddChild(header); } void GUIShaderNode::OnHeaderRightClick(GUIWindow* wnd, int param) { printf("Right click on header!\n"); } void GUIShaderNode::OnHeaderMouseClick(GUIWindow* wnd, int param) { Event_HeaderClick.Invoke(this, param); } void GUIShaderNode::SetDisplayImage(texture_ptr tex) { displayImage = tex; display->SetPicture(CImage::FromTexture(displayImage.ptr())); } void GUIShaderNode::SetCaption(const String& text) { header_text->SetText(text); } const String& GUIShaderNode::GetCaption() { return header_text->GetText(); } GUIShaderNode::~GUIShaderNode() { } void GUIShaderNode::OnBeginResize(GUIWindow* wnd, int param) { resizing = true; FindOverlay()->GrabMouse(wnd); size_pos = body->GetRectangleAbs().GetMax() - FindOverlay()->cursorPos; } void GUIShaderNode::OnDoResize(GUIWindow* wnd, int param) { if(resizing) { Vec2i newPos = FindOverlay()->cursorPos + size_pos; Vec2i diff = newPos - body->GetRectangleAbs().GetMin(); if(diff.X < size_min.X) diff.X = size_min.X; if(diff.Y < size_min.Y) diff.Y = size_min.Y; if(diff.X > size_max.X) diff.X = size_max.X; if(diff.Y > size_max.Y) diff.Y = size_max.Y; body->SetWidth(diff.X); body->SetHeight(diff.Y); header->SetWidth(diff.X); display->SetWidth(body->GetClientRectangle().width - 4); display->SetHeight(body->GetClientRectangle().height - 4); Invalidate(); } } void GUIShaderNode::OnEndResize(GUIWindow* wnd, int param) { resizing = false; FindOverlay()->ReleaseMouse(); } void GUIShaderNode::OnHeaderMouseDown(GUIWindow* wnd, int param) { if(param == KEY_MOUSE_LEFT) { OnSelect(); moving = true; FindOverlay()->GrabMouse(wnd); size_pos = this->GetRectangleAbs().GetMin() - FindOverlay()->cursorPos; } } void GUIShaderNode::OnHeaderMouseMove(GUIWindow* wnd, int param) { if(moving) { Vec2i new_pos = parent->CursorToLocal(FindOverlay()->cursorPos + size_pos); this->SetPosition(new_pos); Invalidate(); } } void GUIShaderNode::OnHeaderMouseUp(GUIWindow* wnd, int param) { if(param == KEY_MOUSE_LEFT) { FindOverlay()->ReleaseMouse(); moving = false; } } void GUIShaderNode::ProcessLink(GUIShaderNodeIO* my, GUIShaderNodeIO* other) { if(my->Owner != other->Owner) { Event_Attach.Invoke(my, other); } } void GUIShaderNode::FormatInputs() { int cnt = inputs.size(); int spacing = 5; if(!cnt) return; int totalSize = spacing * (cnt - 1) + inputs[0]->GetHeight() * cnt; int step = totalSize / cnt; int h = body->GetHeight(); int start = (h - totalSize) / 2 + body->GetPosition().Y; for(int i = 0; i < cnt; i++) { Vec2i pos = inputs[i]->GetPosition(); int newX = body->GetRectangle().GetMaxX(); if(pos.X != newX) Invalidate(); pos.X = newX; pos.Y = start + (step * i); inputs[i]->SetPosition(pos); } } void GUIShaderNode::FormatOutputs() { int cnt = outputs.size(); int spacing = 5; if(!cnt) return; int totalSize = spacing * (cnt - 1) + outputs[0]->GetHeight() * cnt; int step = totalSize / cnt; int h = body->GetHeight(); int start = (h - totalSize) / 2 + body->GetPosition().Y; for(int i = 0; i < cnt; i++) { Vec2i pos = outputs[i]->GetPosition(); int newX = body->GetPosition().X - outputs[i]->GetWidth(); if(pos.X != newX) Invalidate(); pos.X = newX; pos.Y = start + (step * i); outputs[i]->SetPosition(pos); } } void GUIShaderNode::AddInput(GUIShaderNodeIO* node) { node->SetMode(true); node->Event_Link += NewDelegate(this, &GUIShaderNode::ProcessLink); node->Event_Resize += NewDelegate(this, &GUIShaderNode::OnIOResize); node->id = inputs.size(); inputs.push_back(node); node->Owner = this; AddChild(node); FormatInputs(); } void GUIShaderNode::OnIOResize(GUIWindow* wnd) { this->Invalidate(); } void GUIShaderNode::AddOutput(GUIShaderNodeIO* node) { node->SetMode(false); node->Event_Link += NewDelegate(this, &GUIShaderNode::ProcessLink); node->Event_Resize += NewDelegate(this, &GUIShaderNode::OnIOResize); AddChild(node); node->Owner = this; node->id = outputs.size(); outputs.push_back(node); FormatOutputs(); } size_t GUIShaderNode::GetInputCount() { return inputs.size(); } size_t GUIShaderNode::GetOutputCount() { return outputs.size(); } GUIShaderNodeIO* GUIShaderNode::GetInput(int id) { return inputs[id]; } GUIShaderNodeIO* GUIShaderNode::GetOutput(int id) { return outputs[id]; } void GUIShaderNode::OnSelect() { Event_Select.Invoke(this); } void GUIShaderNode::RenderSelf() { if(invalid) { LifeMath::Rect2i tr = childs[0]->GetRectangle(); //find all childs bounding rectangle for(WindowList::iterator it = childs.begin(); it!= childs.end(); ++it) { GUIWindow* w = (*it); tr.Merge(w->GetRectangle()); } int new_width = tr.width; int new_height = tr.height; if(this->width != new_width) this->SetWidth(new_width); if(this->height != new_height) this->SetHeight(new_height); mover->SetPosition(body->GetRectangle().GetMax() - Vec2i(5,5)); //need to move all childs if(tr.x !=0 || tr.y !=0) { for(WindowList::iterator it = childs.begin(); it!= childs.end(); ++it) { GUIWindow* w = (*it); Vec2i pp = w->GetPosition(); w->SetPosition(Vec2i(pp.X - tr.x, pp.Y - tr.y)); } } FormatInputs(); FormatOutputs(); invalid = false; if(parent) parent->Invalidate(); } } void GUIShaderNode::Update(float dt) { } void GUIShaderNode::SetBackColor(const Vec4f& color) { } bool GUIShaderNode::ProcessMessage(GUIMessageType mt, GUIMessageParam mp, IMessageArgs* args) { return false; }