| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- const bool DEFAULT_SHOW_NAMES_FOR_ALL = false;
- const int ORIGIN_STEP_UPDATE = 10;
- const int NAMES_SIZE = 11;
- const StringHash ORIGIN_NODEID_VAR("OriginNodeID");
- const Color ORIGIN_COLOR(1.0f,1.0f,1.0f,1.0f);
- const Color ORIGIN_COLOR_SELECTED(0.0f,1.0f,1.0f,1.0f);
- const Color ORIGIN_COLOR_DISABLED(1.0f,0.0f,0.0f,1.0f);
- const Color ORIGIN_COLOR_TEXT(1.0f,1.0f,1.0f,0.3f);
- const Color ORIGIN_COLOR_SELECTED_TEXT(1.0f,1.0f,1.0f,1.0f);
- const IntVector2 ORIGIN_ICON_SIZE(14,14);
- const IntVector2 ORIGIN_ICON_SIZE_SELECTED(18,18);
- const float ORIGINS_VISIBLITY_RANGE = 32.0f;
- const IntVector2 ORIGINOFFSETICON(8,8);
- const IntVector2 ORIGINOFFSETICONSELECTED(10,8);
- bool showNamesForAll = DEFAULT_SHOW_NAMES_FOR_ALL;
- bool EditorOriginShow = false;
- bool rebuildSceneOrigins = true;
- bool isOriginsHovered = false;
- int EditorOriginUITimeToUpdate = 0;
- int EditorOriginUITimeToSceneNodeRead = 0;
- int prevSelectedID;
- int selectedNodeInfoState = 0;
- int originHoveredIndex = -1;
- UIElement@ EditorOriginUIContainer = null;
- Text@ selectedNodeName = null;
- BorderImage@ selectedNodeOrigin = null;
- Array<BorderImage@> selectedNodeOriginChilds;
- Array<Text@> selectedNodeNameChilds;
- Array<Node@> originsNodes;
- Array<BorderImage@> originsIcons;
- Array<Text@> originsNames;
- void CreateOriginsContainer()
- {
- if (editorScene is null) return;
- EditorOriginUIContainer = UIElement();
- EditorOriginUIContainer.position = IntVector2(0,0);
- EditorOriginUIContainer.size = IntVector2(graphics.width,graphics.height);
- EditorOriginUIContainer.priority = -1000;
- EditorOriginUIContainer.focusMode = FM_NOTFOCUSABLE;
- EditorOriginUIContainer.bringToBack = true;
- EditorOriginUIContainer.name ="DebugOriginsContainer";
- EditorOriginUIContainer.temporary = true;
- ui.root.AddChild(EditorOriginUIContainer);
- }
- void HandleOriginToggled(StringHash eventType, VariantMap& eventData)
- {
- UIElement@ origin = eventData["Element"].GetPtr();
- if (origin is null) return;
- if (EditorPaintSelectionShow) return;
- if (IsSceneOrigin(origin))
- {
- int nodeID = origin.vars[ORIGIN_NODEID_VAR].GetInt();
- if (editorScene !is null)
- {
- bool goBackAndSelectNodeParent = input.qualifierDown[QUAL_CTRL];
- bool multiSelect = input.qualifierDown[QUAL_SHIFT];
- WeakHandle handle = editorScene.GetNode(nodeID);
- if (handle.Get() !is null) {
- Node@ selectedNodeByOrigin = handle.Get();
- if (selectedNodeByOrigin !is null)
- {
- if (goBackAndSelectNodeParent)
- SelectNode(selectedNodeByOrigin.parent, false);
- else
- SelectNode(selectedNodeByOrigin, multiSelect);
- }
- }
- }
- }
- }
- void ShowOrigins(bool isVisible = true)
- {
- EditorOriginShow = isVisible;
- if (EditorOriginUIContainer is null)
- CreateOriginsContainer();
-
- EditorOriginUIContainer.visible = isVisible;
- }
- void UpdateOrigins()
- {
- // Early out if Origins are disabled
- if (!EditorOriginShow) return;
- CheckKeyboardQualifers();
- if (editorScene is null || EditorOriginUITimeToUpdate > time.systemTime) return;
- EditorOriginUIContainer = ui.root.GetChild("DebugOriginsContainer");
- // Since editor not clear UIs then do loading new scenes, this creation called once per Editor's starting event
- // for other scenes we use the same container
- if (EditorOriginUIContainer is null)
- {
- CreateOriginsContainer();
- }
- if (EditorOriginUIContainer !is null)
- {
- // Set visibility for all origins
- EditorOriginUIContainer.visible = EditorOriginShow;
- if (viewportMode!=VIEWPORT_SINGLE)
- EditorOriginUIContainer.visible = false;
-
- // Forced read nodes for some reason:
- if ((originsNodes.length < 1) || rebuildSceneOrigins)
- {
- originsNodes = editorScene.GetChildren(true);
- // If we are hot have free origins icons in arrays, resize x 2
- if (originsIcons.length < originsNodes.length)
- {
- EditorOriginUIContainer.RemoveAllChildren();
- originsIcons.Clear();
- originsNames.Clear();
- originsIcons.Resize(originsNodes.length * 2);
- originsNames.Resize(originsNodes.length * 2);
- if (originsIcons.length > 0)
- {
- for (int i=0; i < originsIcons.length; i++)
- {
- CreateOrigin(i, false);
- }
- }
- }
- // If this rebuild pass after new scene loading or add/delete node - reset flag to default
- if (rebuildSceneOrigins)
- rebuildSceneOrigins = false;
- }
- if (originsNodes.length > 0)
- {
- // Get selected node for feeding proper arrray's UIElements with slyte colorig and additional info on ALT
- Node@ selectedNode = null;
- if (selectedNodes.length > 0)
- {
- selectedNode = selectedNodes[0];
- }
- else if (selectedComponents.length > 0)
- {
- selectedNode = selectedComponents[0].node;
- }
- // Update existed origins (every 10 ms)
- if (originsNodes.length > 0 )
- {
- for (int i=0; i < originsNodes.length; i++)
- {
- Vector3 eyeDir = originsNodes[i].worldPosition - cameraNode.worldPosition;
- float distance = (eyeDir).length;
- eyeDir.Normalize();
- Vector3 cameraDir = (cameraNode.worldRotation * Vector3(0.0f, 0.0f, 1.0f)).Normalized();
- float angleCameraDirVsDirToNode = eyeDir.DotProduct(cameraDir);
- // if node in range and in camera view (clip back sibe)
- if (distance < ORIGINS_VISIBLITY_RANGE && angleCameraDirVsDirToNode > 0.7f)
- {
- // turn on origin and move
- MoveOrigin(i, true);
- if (isThisNodeOneOfSelected(originsNodes[i]))
- {
- ShowSelectedNodeOrigin(originsNodes[i], i);
- originsNames[i].visible = true;
- }
- else
- {
- if (showNamesForAll || (isOriginsHovered && originHoveredIndex == i))
- originsNames[i].text = NodeInfo(originsNodes[i], selectedNodeInfoState);
- }
- }
- else
- {
- // turn-off origin
- VisibilityOrigin(i, false);
- }
- }
- // Hide non used origins
- for (int j=originsNodes.length; j < originsIcons.length; j++)
- {
- VisibilityOrigin(j, false);
- }
- }
- }
- }
- EditorOriginUITimeToUpdate = time.systemTime + ORIGIN_STEP_UPDATE;
- }
- bool isThisNodeOneOfSelected(Node@ node)
- {
- if (selectedNodes.length < 1) return false;
- for (int i = 0; i < selectedNodes.length; i++)
- {
- if (node is selectedNodes[i])
- return true;
- }
- return false;
- }
- void ShowSelectedNodeOrigin(Node@ node, int index)
- {
- if (node !is null)
- {
- // just keep node's text and node's origin icon position in actual view
- Viewport@ vp = activeViewport.viewport;
- Vector2 sp = activeViewport.camera.WorldToScreenPoint(node.worldPosition);
- //originsIcons[index].position = IntVector2(10+int(vp.rect.left + sp.x * vp.rect.right), -5 + int(vp.rect.top + sp.y* vp.rect.bottom));
- originsIcons[index].position = IntVector2(int(vp.rect.left + sp.x * vp.rect.right) - ORIGINOFFSETICONSELECTED.x, int(vp.rect.top + sp.y* vp.rect.bottom) - ORIGINOFFSETICONSELECTED.y);
- originsNames[index].color = ORIGIN_COLOR_SELECTED_TEXT;
- if (originsNodes[index].enabled)
- originsIcons[index].color = ORIGIN_COLOR_SELECTED;
- else
- originsIcons[index].color = ORIGIN_COLOR_DISABLED;
-
- originsIcons[index].SetFixedSize(ORIGIN_ICON_SIZE_SELECTED.x,ORIGIN_ICON_SIZE_SELECTED.y);
- // if selected node chaged, reset some vars
- if (prevSelectedID != node.id)
- {
- prevSelectedID = node.id;
- selectedNodeInfoState = 0;
- originsIcons[index].vars[ORIGIN_NODEID_VAR] = node.id;
- }
- // We always update to keep and feed alt-info with actual info about node components
- Array<Component@> components = node.GetComponents();
- Array<String> componentsShortInfo;
- Array<String> componentsDetailInfo;
- componentsShortInfo.Resize(components.length);
- componentsDetailInfo.Resize(components.length);
- // Add std info node name + tags
- originsNames[index].text = NodeInfo(node, selectedNodeInfoState) + "\n";
- }
- }
- void CreateOrigin(int index, bool isVisible = false)
- {
- if (originsIcons.length < index) return;
- originsIcons[index] = BorderImage("Icon");
- originsIcons[index].temporary = true;
- originsIcons[index].SetFixedSize(ORIGIN_ICON_SIZE.x,ORIGIN_ICON_SIZE.y);
- originsIcons[index].texture = cache.GetResource("Texture2D", "Textures/Editor/EditorIcons.png");
- originsIcons[index].imageRect = IntRect(0,0,14,14);
- originsIcons[index].priority = -1000;
- originsIcons[index].color = ORIGIN_COLOR;
- originsIcons[index].bringToBack = true;
- originsIcons[index].enabled = true;
- originsIcons[index].selected = true;
- originsIcons[index].visible = isVisible;
- EditorOriginUIContainer.AddChild(originsIcons[index]);
- originsNames[index] = Text();
- originsNames[index].visible = false;
- originsNames[index].SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), NAMES_SIZE);
- originsNames[index].color = ORIGIN_COLOR_TEXT;
- //originsNames[index].textEffect = TE_STROKE;
- originsNames[index].temporary = true;
- originsNames[index].bringToBack = true;
- originsNames[index].priority = -1000;
- originsNames[index].enabled = false;
- EditorOriginUIContainer.AddChild(originsNames[index]);
- }
- void MoveOrigin(int index, bool isVisible = false)
- {
- if (originsIcons.length < index) return;
- if (originsIcons[index] is null) return;
- if (originsNodes[index].temporary)
- {
- originsIcons[index].visible = false;
- originsNames[index].visible = false;
- return;
- }
- Viewport@ vp = activeViewport.viewport;
- Vector2 sp = activeViewport.camera.WorldToScreenPoint(originsNodes[index].worldPosition);
- originsIcons[index].SetFixedSize(ORIGIN_ICON_SIZE.x,ORIGIN_ICON_SIZE.y);
- if (originsNodes[index].enabled)
- originsIcons[index].color = ORIGIN_COLOR;
- else
- originsIcons[index].color = ORIGIN_COLOR_DISABLED;
- originsIcons[index].position = IntVector2(int(vp.rect.left + sp.x * vp.rect.right) - ORIGINOFFSETICON.x, int(vp.rect.top + sp.y* vp.rect.bottom) - ORIGINOFFSETICON.y);
- originsIcons[index].visible = isVisible;
- originsIcons[index].vars[ORIGIN_NODEID_VAR] = originsNodes[index].id;
- originsNames[index].position = IntVector2(10+int(vp.rect.left + sp.x * vp.rect.right), -5 + int(vp.rect.top + sp.y* vp.rect.bottom));
- if (isOriginsHovered && originHoveredIndex == index)
- {
- originsNames[index].visible = true;
- originsNames[index].color = ORIGIN_COLOR_SELECTED_TEXT;
- }
- else
- {
- originsNames[index].visible = showNamesForAll ? isVisible : false;
- originsNames[index].color = ORIGIN_COLOR_TEXT;
- }
- }
- void VisibilityOrigin(int index, bool isVisible = false)
- {
- originsIcons[index].visible = isVisible;
- originsNames[index].visible = isVisible;
- }
- bool IsSceneOrigin(UIElement@ element)
- {
- if (originsIcons.length < 1) return false;
- for (int i=0; i < originsIcons.length; i++)
- {
- if (element is originsIcons[i])
- {
- originHoveredIndex = i;
- return true;
- }
- }
- originHoveredIndex = -1;
- return false;
- }
- void CheckKeyboardQualifers()
- {
- // if pressed alt we inc state for info
- bool showAltInfo = input.keyPress[KEY_ALT];
- if (showAltInfo)
- if (selectedNodeInfoState < 3) selectedNodeInfoState += 1;
- // if pressed ctrl we reset info state
- bool hideAltInfo = input.qualifierDown[QUAL_CTRL];
- if (hideAltInfo)
- selectedNodeInfoState = 0;
- bool showNameForOther = false;
- // In-B.mode Key_Space are busy by quick menu, so we use other key for B.mode
- if (hotKeyMode == HOTKEYS_MODE_BLENDER)
- showNameForOther = (input.keyPress[KEY_TAB] && ui.focusElement is null);
- else
- showNameForOther = (input.keyPress[KEY_SPACE] && ui.focusElement is null);
- if (showNameForOther)
- showNamesForAll =!showNamesForAll;
- }
- String NodeInfo(Node& node, int st)
- {
- String result = "";
- if (node !is editorScene)
- {
- if (node.name.empty)
- result = "Node";
- else
- result = node.name;
- // Add node's tags if wey are exist
- if (st > 0 && node.tags.length > 0)
- {
- result = result + "\n[";
- for (int i=0;i<node.tags.length; i++)
- {
- result = result + " " + node.tags[i];
- }
- result = result + " ] ";
- }
- }
- else
- result = "Scene Origin";
- return result;
- }
- void HandleSceneLoadedForOrigins()
- {
- rebuildSceneOrigins = true;
- }
- void HandleOriginsHoverBegin(StringHash eventType, VariantMap& eventData)
- {
- UIElement@ origin = eventData["Element"].GetPtr();
- if (origin is null)
- return;
- if (IsSceneOrigin(origin))
- {
- VariantMap data;
- data["Element"] = originsIcons[originHoveredIndex];
- data["Id"] = originHoveredIndex;
- data["NodeId"] = originsIcons[originHoveredIndex].vars[ORIGIN_NODEID_VAR].GetInt();
- SendEvent(EDITOR_EVENT_ORIGIN_START_HOVER, data);
- isOriginsHovered = true;
- }
- }
- void HandleOriginsHoverEnd(StringHash eventType, VariantMap& eventData)
- {
- UIElement@ origin = eventData["Element"].GetPtr();
- if (origin is null)
- return;
- if (IsSceneOrigin(origin))
- {
- VariantMap data;
- data["Element"] = originsIcons[originHoveredIndex];
- data["Id"] = originHoveredIndex;
- data["NodeId"] = originsIcons[originHoveredIndex].vars[ORIGIN_NODEID_VAR].GetInt();
- SendEvent(EDITOR_EVENT_ORIGIN_END_HOVER, data);
- isOriginsHovered = false;
- }
- }
|