private void DrawReviewDistantsElements()
        {
            EditorGUILayout.LabelField("Distant Devices", EditorStyles.boldLabel);
            GUILayout.Label($"<b>{Tab.DistantSlaves.Count}</b> slave {(Tab.DistantSlaves.Count == 1 ? "device was" : "devices were")} "
                            + "too far from a master device for connection.", EditorUIUtils.LabelStyle);
            GUILayout.BeginHorizontal();
            bool btnPrevious = GUILayout.Button("Previous");
            bool btnNext     = GUILayout.Button("Next");

            GUILayout.EndHorizontal();

            if (btnPrevious)
            {
                Tab.ReviewDistantSlaveIndex--;
            }
            if (btnNext)
            {
                Tab.ReviewDistantSlaveIndex++;
            }

            if (btnPrevious || btnNext)
            {
                Tab.ReviewDistantSlaveNewDistance = -1;
                Tab.ReviewDistantSlaveIndex       = Mathf.Clamp(Tab.ReviewDistantSlaveIndex, 0, Tab.DistantSlaves.Count - 1);

                Selection.activeGameObject = Tab.DistantSlaves[Tab.ReviewDistantSlaveIndex].gameObject;
                SceneView.FrameLastActiveSceneView();
            }

            if (Tab.ReviewDistantSlaveIndex > -1)
            {
                var slaveUnderReview = Tab.DistantSlaves[Tab.ReviewDistantSlaveIndex];

                if (EditorUIUtils.BigAssButton("Retry"))
                {
                    Tab.ReviewDistantSlaveNewDistance = DeviceLinker.TryLinkSlaveToClosestMaster(slaveUnderReview);
                    EditorUtility.SetDirty((Component)slaveUnderReview);
                }

                if (Tab.ReviewDistantSlaveNewDistance > DeviceLinker.Masters[0].MaxDistance)
                {
                    GUILayout.Label($"<b>{slaveUnderReview.gameObject.name}</b>: maximum distance of <b>{DeviceLinker.Masters[0].MaxDistance}</b> " +
                                    $"tiles exceeded; distance to nearest master found to be <b>{Tab.ReviewDistantSlaveNewDistance, 0:N}</b> tiles.",
                                    EditorUIUtils.LabelStyle);
                }
                else if (slaveUnderReview.Master != null)
                {
                    GUILayout.Label($"<b>{slaveUnderReview.gameObject.name}</b> has been relinked.", EditorUIUtils.LabelStyle);
                }
                else
                {
                    GUILayout.Label($"<b>{slaveUnderReview.gameObject.name}</b>'s link status is uncertain.", EditorUIUtils.LabelStyle);
                }
            }
        }
        private void OnGUI()
        {
            EditorGUILayout.Space();
            activeWindowTab = GUILayout.Toolbar(activeWindowTab, tabs.Select(info => info.Name).ToArray());
            EditorGUILayout.Space();

            if (activeWindowTab != previousWindowTab)
            {
                DeviceLinker.InitDeviceLists(Tab.Type);
                previousWindowTab = activeWindowTab;
            }

            DrawUiElements();
        }
        private void OnEnable()
        {
            titleContent = new GUIContent("Device Linker");
            var windowSize = minSize;

            windowSize.x = 250;
            minSize      = windowSize;

            PopulateTabs();

            EditorSceneManager.sceneOpened += (oldScene, newScene) =>
            {
                PopulateTabs();
                DeviceLinker.InitDeviceLists(Tab.Type, forceRefresh: true);
            };
        }
        private int LinkSlaves(bool relinkConnected)
        {
            int count = DeviceLinker.Slaves.Count(slave => {
                if (slave.RequireLink == false)
                {
                    if (Tab.IgnoredSlaves.Contains(slave) == false)
                    {
                        Tab.IgnoredSlaves.Add(slave);
                    }

                    return(false);
                }


                if (slave.Master != null && relinkConnected == false)
                {
                    return(false);
                }

                float distance = DeviceLinker.TryLinkSlaveToClosestMaster(slave);
                if (distance > DeviceLinker.Masters[0].MaxDistance)
                {
                    if (Tab.DistantSlaves.Contains(slave) == false)
                    {
                        Tab.DistantSlaves.Add(slave);
                    }

                    return(false);
                }

                EditorUtility.SetDirty((Component)slave);
                return(true);
            });

            EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
            return(count);
        }