void ShaderEditor::_input_event(InputEvent p_event) {

	switch(p_event.type) {

		case InputEvent::MOUSE_BUTTON: {

			if (p_event.mouse_button.pressed) {


				if (p_event.mouse_button.button_index==1) {
					click_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
					click_motion=click_pos;
					click_type = _locate_click(click_pos,&click_node,&click_slot);
					if( click_type!=CLICK_NONE) {

						order.erase(click_node);
						order.push_back(click_node);
						update();
					}
					switch(click_type) {
						case CLICK_INPUT_SLOT: {
							click_pos=_get_slot_pos(click_node,true,click_slot);
						} break;
						case CLICK_OUTPUT_SLOT: {
							click_pos=_get_slot_pos(click_node,false,click_slot);
						} break;
						case CLICK_PARAMETER: {
							//open editor
							_node_edit_property(click_node);
						} break;
					}
				}
				if (p_event.mouse_button.button_index==2) {

					if (click_type!=CLICK_NONE) {
						click_type=CLICK_NONE;
						update();
					} else {
						// try to disconnect/remove

						Point2 rclick_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
						rclick_type = _locate_click(rclick_pos,&rclick_node,&rclick_slot);
						if (rclick_type==CLICK_INPUT_SLOT || rclick_type==CLICK_OUTPUT_SLOT) {

							node_popup->clear();
							node_popup->add_item("Disconnect",NODE_DISCONNECT);
							node_popup->set_pos(rclick_pos);
							node_popup->popup();

						}

						if (rclick_type==CLICK_NODE) {
							node_popup->clear();
							node_popup->add_item("Remove",NODE_ERASE);
							node_popup->set_pos(rclick_pos);
							node_popup->popup();
						}


					}
				}
			} else {

				if (p_event.mouse_button.button_index==1 && click_type!=CLICK_NONE) {

					switch(click_type) {
						case CLICK_INPUT_SLOT:
						case CLICK_OUTPUT_SLOT: {

							Point2 dst_click_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
							int id;
							int slot;
							ClickType dst_click_type = _locate_click(dst_click_pos,&id,&slot);
							if (dst_click_type==CLICK_INPUT_SLOT && click_type==CLICK_OUTPUT_SLOT) {

								shader_graph.connect(click_node,click_slot,id,slot);

								Error err = validate_graph();
								if (err==ERR_CYCLIC_LINK)
									shader_graph.disconnect(click_node,click_slot,id,slot);
								_write_shader_graph();

							}
							if (click_type==CLICK_INPUT_SLOT && dst_click_type==CLICK_OUTPUT_SLOT) {

								shader_graph.connect(id,slot,click_node,click_slot);

								Error err = validate_graph();
								if (err==ERR_CYCLIC_LINK)
									shader_graph.disconnect(id,slot,click_node,click_slot);
								_write_shader_graph();
							}

						} break;
						case CLICK_NODE: {
							int new_x=shader_graph.node_get_pos_x(click_node)+(click_motion.x-click_pos.x);
							int new_y=shader_graph.node_get_pos_y(click_node)+(click_motion.y-click_pos.y);
							shader_graph.node_set_pos(click_node,new_x,new_y);
							_write_shader_graph();

						} break;
					}

					click_type=CLICK_NONE;
					update();
				}
			}

		}

		case InputEvent::MOUSE_MOTION: {

			if (p_event.mouse_motion.button_mask&1 && click_type!=CLICK_NONE) {

				click_motion=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
				update();
			}

		} break;
	}
}
void AnimationTreeEditor::_input_event(InputEvent p_event) {

	switch(p_event.type) {

		case InputEvent::MOUSE_BUTTON: {

			if (p_event.mouse_button.pressed) {


				if (p_event.mouse_button.button_index==1) {
					click_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
					click_motion=click_pos;
					click_type = _locate_click(click_pos,&click_node,&click_slot);
					if( click_type!=CLICK_NONE) {

						order.erase(click_node);
						order.push_back(click_node);
						update();
					}

					switch(click_type) {
						case CLICK_INPUT_SLOT: {
							click_pos=_get_slot_pos(click_node,true,click_slot);
						} break;
						case CLICK_OUTPUT_SLOT: {
							click_pos=_get_slot_pos(click_node,false,click_slot);
						} break;
						case CLICK_PARAMETER: {

							edited_node=click_node;
							renaming_edit=false;
							_popup_edit_dialog();
							//open editor
					//		_node_edit_property(click_node);
						} break;
						default:{}
					}
				}
				if (p_event.mouse_button.button_index==2) {

					if (click_type!=CLICK_NONE) {
						click_type=CLICK_NONE;
						update();
					} else {
						// try to disconnect/remove

						Point2 rclick_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
						rclick_type = _locate_click(rclick_pos,&rclick_node,&rclick_slot);
						if (rclick_type==CLICK_INPUT_SLOT || rclick_type==CLICK_OUTPUT_SLOT) {

							node_popup->clear();
							node_popup->add_item(TTR("Disconnect"),NODE_DISCONNECT);
							if (anim_tree->node_get_type(rclick_node)==AnimationTreePlayer::NODE_TRANSITION) {
								node_popup->add_item(TTR("Add Input"),NODE_ADD_INPUT);
								if (rclick_type==CLICK_INPUT_SLOT) {
									if (anim_tree->transition_node_has_input_auto_advance(rclick_node,rclick_slot))
										node_popup->add_item(TTR("Clear Auto-Advance"),NODE_CLEAR_AUTOADVANCE);
									else
										node_popup->add_item(TTR("Set Auto-Advance"),NODE_SET_AUTOADVANCE);
									node_popup->add_item(TTR("Delete Input"),NODE_DELETE_INPUT);

								}
							}

							node_popup->set_pos(rclick_pos+get_global_pos());
							node_popup->popup();

						}

						if (rclick_type==CLICK_NODE) {
							node_popup->clear();
							node_popup->add_item(TTR("Rename"),NODE_RENAME);
							node_popup->add_item(TTR("Remove"),NODE_ERASE);
							if (anim_tree->node_get_type(rclick_node)==AnimationTreePlayer::NODE_TRANSITION)
								node_popup->add_item(TTR("Add Input"),NODE_ADD_INPUT);
							node_popup->set_pos(rclick_pos+get_global_pos());
							node_popup->popup();
						}


					}
				}
			} else {

				if (p_event.mouse_button.button_index==1 && click_type!=CLICK_NONE) {

					switch(click_type) {
						case CLICK_INPUT_SLOT:
						case CLICK_OUTPUT_SLOT: {

							Point2 dst_click_pos=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
							StringName id;
							int slot;
							ClickType dst_click_type = _locate_click(dst_click_pos,&id,&slot);

							if (dst_click_type==CLICK_INPUT_SLOT && click_type==CLICK_OUTPUT_SLOT) {

								anim_tree->connect(click_node,id,slot);

							}
							if (click_type==CLICK_INPUT_SLOT && dst_click_type==CLICK_OUTPUT_SLOT) {

								anim_tree->connect(id,click_node,click_slot);
							}

						} break;
						case CLICK_NODE: {
							Point2 new_pos = anim_tree->node_get_pos(click_node)+(click_motion-click_pos);
							if (new_pos.x<5)
								new_pos.x=5;
							if (new_pos.y<5)
								new_pos.y=5;
							anim_tree->node_set_pos(click_node,new_pos);

						} break;
						default: {}
					}

					click_type=CLICK_NONE;
					update();
				}
			}
		}

		case InputEvent::MOUSE_MOTION: {

			if (p_event.mouse_motion.button_mask&1 && click_type!=CLICK_NONE) {

				click_motion=Point2(p_event.mouse_button.x,p_event.mouse_button.y);
				update();
			}
			if ((p_event.mouse_motion.button_mask&4 || Input::get_singleton()->is_key_pressed(KEY_SPACE))) {

				h_scroll->set_val( h_scroll->get_val() - p_event.mouse_motion.relative_x );
				v_scroll->set_val( v_scroll->get_val() - p_event.mouse_motion.relative_y );
				update();
			}

		} break;
	}

}
bool ShaderEditor::has_point(const Point2& p_point) const {

	int n,si;

	return _locate_click(p_point,&n,&si)!=CLICK_NONE;
}