private void NodeControl_MouseDown(object sender, MouseButtonEventArgs e)
        {
            CaptureMouse();

            scene_rendering_control.UpdateMouseTracking(e, true);

            if (e.LeftButton == MouseButtonState.Pressed)
            {
                scene_rendering_control.selected_connector_control.Selected = null;

                if ((Keyboard.Modifiers & ModifierKeys.Alt) > 0)
                {
                    NodeControl nc_linked = sender as NodeControl;

                    foreach (NodeControl node_control in scene_rendering_control.GetSelectedNodeControls())
                    {
                        ConnectorControl cc = new ConnectorControl(scene_rendering_control);
                        cc.SetNodes(node_control, nc_linked);
                        scene_rendering_control.AddNewConnectorControl(cc);
                    }
                }
                else
                {
                    if (!scene_rendering_control.IsSelectedNodeControl(this))
                    {
                        scene_rendering_control.SetSelectedNodeControl(sender as NodeControl, scene_rendering_control.IsUserIndicatingAddToSelection());
                        scene_rendering_control.selected_connector_control.Selected = null;
                    }
                }

                e.Handled = true;
            }
        }
Exemplo n.º 2
0
        public void Add(ConnectorControl connector_control)
        {
            connector_controls.Add(connector_control);

            links_from_to.Add(connector_control.node_from, connector_control);
            links_from_to.Add(connector_control.node_to, connector_control);
        }
 public ItemConnector(FrameworkElement parent, double width, double height)
 {
     _uiControl        = new ConnectorControl(parent);
     _uiControl.Width  = width;
     _uiControl.Height = height;
     UIElement         = _uiControl;
 }
        internal static void AddSiblingToNodeControl(NodeControl node_control)
        {
            List <ConnectorControl> connectors_both;
            List <ConnectorControl> connectors_to;
            List <ConnectorControl> connectors_from;

            GetAdjoiningConnectors(node_control.scene_rendering_control, node_control, out connectors_both, out connectors_to, out connectors_from);

            double left   = node_control.scene_data.CentreX;
            double top    = node_control.scene_data.CentreY;
            double width  = node_control.scene_data.Width;
            double height = node_control.scene_data.Height;

            top += 1.5 * height;

            NodeControlSceneData scene_data = new NodeControlSceneData();
            object      content             = new StringNodeContent("Sibling node");
            NodeControl node_new            = node_control.scene_rendering_control.AddNewNodeControl(content, left, top, width, height);

            if (connectors_to.Count > 0)
            {
                NodeControl node_control_parent = connectors_to[connectors_to.Count - 1].node_from;

                ConnectorControl connector_new = new ConnectorControl(node_control.scene_rendering_control);
                connector_new.SetNodes(node_control_parent, node_new);
                node_control.scene_rendering_control.AddNewConnectorControl(connector_new);
            }

            node_control.scene_rendering_control.SetSelectedNodeControl(node_new, false);
        }
        void SelectedConnector_OnDimensionsChanged(ConnectorControl cc)
        {
            double SPACER = 4;

            this.Width  = cc.Width + SPACER + SPACER;
            this.Height = cc.Height + SPACER + SPACER;

            Canvas.SetLeft(this, Canvas.GetLeft(cc) - SPACER);
            Canvas.SetTop(this, Canvas.GetTop(cc) - SPACER);
            Canvas.SetZIndex(this, Canvas.GetZIndex(cc) + 1);
        }
Exemplo n.º 6
0
        private static void CreateSampleScene(SceneRenderingControl scene_rendering_control, double x, double y, double skew)
        {
            int N = 300;

            Random random = new Random();

            string[] icon_filenames = new string[] { "papers/binoculars", "papers/boat", "papers/flame", "papers/radioactive", "papers/bread", "papers/news", "papers/music", "papers/percentage", "papers/postit" };

            NodeControl[] ncs = new NodeControl[N];
            for (int i = 0; i < N; ++i)
            {
                object node_content;

                switch (i % 2)
                {
                case 0:
                {
                    IconNodeContent icon_node_content = new IconNodeContent(icon_filenames[random.Next(icon_filenames.Length)]);
                    node_content = icon_node_content;
                    break;
                }

                case 1:
                {
                    StringNodeContent snc = new StringNodeContent();
                    snc.Text     = String.Format("Button {0}", i);
                    node_content = snc;
                    break;
                }

                default:
                    node_content = null;
                    break;
                }

                double raw_angle = 6 * i * Math.PI / 100;
                double distance  = 10 + i * 4 + RandomAugmented.Instance.NextDouble() * 10;
                double left      = x + distance * (-2 + skew) * Math.Sin(raw_angle) + RandomAugmented.Instance.NextDouble() * 30 - 15;
                double top       = y + distance * (+2 + skew) * Math.Cos(raw_angle) + RandomAugmented.Instance.NextDouble() * 30 - 15;

                ncs[i] = scene_rendering_control.AddNewNodeControl(node_content, left, top);

                // A line for this to the prev nc
                if (i > 3 && (i / 2) % 20 == 0)
                {
                    for (int j = 0; j < 3; ++j)
                    {
                        ConnectorControl cc = new ConnectorControl(scene_rendering_control);
                        cc.SetNodes(ncs[i - j], ncs[i]);
                        scene_rendering_control.AddNewConnectorControl(cc);
                    }
                }
            }
        }
Exemplo n.º 7
0
        private void AddNewConnector(object sender, RoutedEventArgs e)
        {
            var tempConnector = new ConnectorControl()
            {
                PositionOnElement = Position.center, ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY
            };

            cWorkSpace.Children.Add(tempConnector);
            tempConnector.AddMenuFlyout();
            Canvas.SetLeft(tempConnector, CursorPosition.X);
            Canvas.SetTop(tempConnector, CursorPosition.Y);
        }
Exemplo n.º 8
0
        private void DoLayout()
        {
            int SPEED = 1;

            // If the nodes and connectors have changed, recache them!
            if (cache_scene_changed_timestamp != this.scene_rendering_control.SceneChangedTimestamp)
            {
                Logging.Info("Scene has changed, so autolayout is recaching.");
                cache_scene_changed_timestamp = this.scene_rendering_control.SceneChangedTimestamp;
                cache_node_controls           = new List <NodeControl>(this.scene_rendering_control.NodeControls);
                cache_connector_controls      = new List <ConnectorControl>(this.scene_rendering_control.ConnectorControlManager.ConnectorControls);
            }

            // We reuse this so that it is memory allocation time efficient
            NodesVector vector = new NodesVector();

            // Perform the attraction
            if (true)
            {
                int MAX_CONNECTORS = cache_connector_controls.Count;
                for (int i = 0; i < MAX_CONNECTORS; ++i)
                {
                    ConnectorControl connector = cache_connector_controls[i];
                    if (connector.Deleted)
                    {
                        continue;
                    }

                    NodeControlSceneData nodeI = connector.NodeFrom.NodeControlSceneData;
                    NodeControlSceneData nodeJ = connector.NodeTo.NodeControlSceneData;

                    vector.Recalculate(nodeI, nodeJ);

                    double strength = -1 * SPEED * (vector.distance / vector.minimum_extent);
                    DoPushPull(nodeI, nodeJ, vector, strength);
                }
            }

            // Perform the repulsion
            if (true)
            {
                int MAX_NODES = cache_node_controls.Count;
                for (int i = 0; i < MAX_NODES; ++i)
                {
                    NodeControlSceneData nodeI = cache_node_controls[i].NodeControlSceneData;
                    if (nodeI.Deleted)
                    {
                        continue;
                    }

                    for (int j = i + 1; j < MAX_NODES; ++j)
                    {
                        NodeControlSceneData nodeJ = cache_node_controls[j].NodeControlSceneData;
                        if (nodeJ.Deleted)
                        {
                            continue;
                        }

                        vector.Recalculate(nodeI, nodeJ);

                        double strength = SPEED * Math.Min(2, (vector.minimum_extent / (vector.box_distance + 1)));
                        DoPushPull(nodeI, nodeJ, vector, strength);
                    }
                }
            }

            NotifySceneRenderingControl();
        }
 void SelectedConnector_OnDeleted(ConnectorControl cc)
 {
     this.Selected = null;
 }
Exemplo n.º 10
0
        private void DoLayout()
        {
            int SPEED = 1;

            // If the nodes and connectors have changed, recache them!
            if (cache_scene_changed_timestamp != scene_rendering_control.SceneChangedTimestamp)
            {
                Logging.Info("Scene has changed, so autolayout is recaching.");
                cache_scene_changed_timestamp = scene_rendering_control.SceneChangedTimestamp;
                cache_node_controls           = new List <NodeControl>(scene_rendering_control.NodeControls);
                cache_connector_controls      = new List <ConnectorControl>(scene_rendering_control.ConnectorControlManager.ConnectorControls);
            }

            // We reuse this so that it is memory allocation time efficient
            NodesVector vector = new NodesVector();

            // Also note that Utilities codebase had ATTRACTION *before* REPULSION.
            // Haven't looked at the precise code, but wouldn't be surprised if this is
            // very similar to the D3 force anneal code (D3.js) anyway. There aren't that
            // many ways to stabilize a (large) graph in 2D.
            //
            // See also https://github.com/jimmejardine/qiqqa-open-source/issues/26

            // Perform the repulsion
            if (true)
            {
                int MAX_NODES = cache_node_controls.Count;
                for (int i = 0; i < MAX_NODES; ++i)
                {
                    NodeControlSceneData nodeI = cache_node_controls[i].NodeControlSceneData;
                    if (nodeI.Deleted)
                    {
                        continue;
                    }

                    for (int j = i + 1; j < MAX_NODES; ++j)
                    {
                        NodeControlSceneData nodeJ = cache_node_controls[j].NodeControlSceneData;
                        if (nodeJ.Deleted)
                        {
                            continue;
                        }

                        vector.Recalculate(nodeI, nodeJ);

                        // Utilities code had:
                        //
                        // See also https://github.com/jimmejardine/qiqqa-open-source/issues/26
#if UNUSED_CODE
                        double strength = SPEED * Math.Min(2, (vector.minimum_extent / (vector.box_distance + 1)));
                        DoPushPull(nodeI, nodeJ, vector, strength);
#else
                        // Qiqqa code chunk alt:
                        double strength = vector.maximum_extent * SPEED * (1 / (vector.box_distance + 1));
                        strength = Math.Min(strength, 5);
                        if (strength > 10)
                        {
                        }
                        // end of Qiqqa alt chunk; looks to me like someone has been fiddling around here...
                        // (including the logline below, which was also not in Utilities codebase...
                        DoPushPull(nodeI, nodeJ, vector, strength);
                        //Logging.Info("REPULSE STRENGTH={0}, box.distance={1}", strength, vector.box_distance);
#endif
                    }
                }
            }

            // Perform the attraction
            if (true)
            {
                int MAX_CONNECTORS = cache_connector_controls.Count;
                for (int i = 0; i < MAX_CONNECTORS; ++i)
                {
                    ConnectorControl connector = cache_connector_controls[i];
                    if (connector.Deleted)
                    {
                        continue;
                    }

                    NodeControlSceneData nodeI = connector.NodeFrom.NodeControlSceneData;
                    NodeControlSceneData nodeJ = connector.NodeTo.NodeControlSceneData;

                    vector.Recalculate(nodeI, nodeJ);

#if UNUSED_CODE
                    // Utilities codebase was:
                    // See also https://github.com/jimmejardine/qiqqa-open-source/issues/26
                    double strength = -1 * SPEED * (vector.distance / vector.minimum_extent);
                    DoPushPull(nodeI, nodeJ, vector, strength);
#else
                    double strength = -1 * SPEED * (vector.box_distance / 50);
                    DoPushPull(nodeI, nodeJ, vector, strength);
                    //Logging.Info("ATTRACT STRENGTH={0}", strength);
#endif
                }
            }

            NotifySceneRenderingControl();
        }
        public static void CreateSampleScene_Coordinates(SceneRenderingControl scene_rendering_control)
        {
            int EXTENT = 30;
            int SCALE  = 100;

            NodeControl nx = scene_rendering_control.AddNewNodeControl(new StringNodeContent()
            {
                Text = "nx"
            }, -2 * SCALE * EXTENT, 0, 100, 100);
            NodeControl px = scene_rendering_control.AddNewNodeControl(new StringNodeContent()
            {
                Text = "px"
            }, +2 * SCALE * EXTENT, 0, 100, 100);
            NodeControl ny = scene_rendering_control.AddNewNodeControl(new StringNodeContent()
            {
                Text = "ny"
            }, 0, -2 * SCALE * EXTENT, 100, 100);
            NodeControl py = scene_rendering_control.AddNewNodeControl(new StringNodeContent()
            {
                Text = "py"
            }, 0, +2 * SCALE * EXTENT, 100, 100);

            for (int x = -EXTENT; x <= EXTENT; ++x)
            {
                for (int y = -EXTENT; y <= EXTENT; ++y)
                {
                    double width  = 100 / (1 + Math.Abs(x) + Math.Abs(y));
                    double height = 100 / (1 + Math.Abs(x) + Math.Abs(y));

                    double xpos = x * SCALE;
                    double ypos = y * SCALE;

                    StringNodeContent snc = new StringNodeContent();
                    snc.Text = String.Format("{0} {1}", xpos, ypos);

                    NodeControl node_control = scene_rendering_control.AddNewNodeControl(snc, xpos, ypos, width, height);

                    if (x == -EXTENT)
                    {
                        ConnectorControl cc = new ConnectorControl(scene_rendering_control);
                        cc.SetNodes(nx, node_control);
                        scene_rendering_control.AddNewConnectorControl(cc);
                    }
                    if (x == +EXTENT)
                    {
                        ConnectorControl cc = new ConnectorControl(scene_rendering_control);
                        cc.SetNodes(px, node_control);
                        scene_rendering_control.AddNewConnectorControl(cc);
                    }
                    if (y == -EXTENT)
                    {
                        ConnectorControl cc = new ConnectorControl(scene_rendering_control);
                        cc.SetNodes(ny, node_control);
                        scene_rendering_control.AddNewConnectorControl(cc);
                    }
                    if (y == +EXTENT)
                    {
                        ConnectorControl cc = new ConnectorControl(scene_rendering_control);
                        cc.SetNodes(py, node_control);
                        scene_rendering_control.AddNewConnectorControl(cc);
                    }
                }
            }
        }
        public static void AddChildToNodeControl(NodeControl node_control_parent, object content, bool select_node)
        {
            List <ConnectorControl> connectors_both;
            List <ConnectorControl> connectors_to;
            List <ConnectorControl> connectors_from;

            GetAdjoiningConnectors(node_control_parent.scene_rendering_control, node_control_parent, out connectors_both, out connectors_to, out connectors_from);

            // Get the average connectors direction
            Point direction_inbound = new Point(0, 0);
            int   denominator       = 0;

            foreach (ConnectorControl connector in connectors_to)
            {
                if (connector.Deleted)
                {
                    continue;
                }

                direction_inbound.X += connector.node_to.NodeControlSceneData.CentreX - connector.node_from.NodeControlSceneData.CentreX;
                direction_inbound.Y += connector.node_to.NodeControlSceneData.CentreY - connector.node_from.NodeControlSceneData.CentreY;
                denominator         += 1;
            }

            if (0 < denominator)
            {
                direction_inbound.X /= denominator;
                direction_inbound.Y /= denominator;
            }
            else
            {
                double angle         = Math.PI * 140.0 / 180.0 * (1 + connectors_from.Count);
                double max_dimension = Math.Max(node_control_parent.scene_data.Width, node_control_parent.scene_data.Height);
                direction_inbound.X = 1.5 * max_dimension * Math.Cos(angle);
                direction_inbound.Y = 1.5 * max_dimension * Math.Sin(angle);
            }

            // Pick an outward direction
            Point  direction_outbound = new Point(direction_inbound.X, direction_inbound.Y);
            double total_divergence   = 0.0;

            if (connectors_to.Count > 0)
            {
                double current_divergence = Math.PI / 4;
                int    i = connectors_from.Count;
                while (i > 0)
                {
                    int remainder = i % 2;
                    if (remainder > 0)
                    {
                        total_divergence += current_divergence;
                    }
                    else
                    {
                        total_divergence -= current_divergence;
                    }

                    current_divergence = current_divergence / 2;
                    i = i / 2;
                }
            }

            // Rotate the direction
            Point direction_outbound_rotated = new Point();

            direction_outbound_rotated.X = direction_outbound.X * Math.Cos(total_divergence) + direction_outbound.Y * Math.Sin(total_divergence);
            direction_outbound_rotated.Y = -direction_outbound.X * Math.Sin(total_divergence) + direction_outbound.Y * Math.Cos(total_divergence);

            double CHILD_SHRINKAGE_FACTOR = 0.8;

            double left = node_control_parent.scene_data.CentreX + direction_outbound_rotated.X * CHILD_SHRINKAGE_FACTOR;
            double top  = node_control_parent.scene_data.CentreY + direction_outbound_rotated.Y * CHILD_SHRINKAGE_FACTOR;

            //xxxxxxxxxxxxxxxxxxxxxxxxx
            double width  = node_control_parent.scene_data.Width * CHILD_SHRINKAGE_FACTOR;
            double height = node_control_parent.scene_data.Height * CHILD_SHRINKAGE_FACTOR;

            // Create a node at the outbound direction
            NodeControl node_new = node_control_parent.scene_rendering_control.AddNewNodeControl(content, left, top, width, height);

            if (node_new != node_control_parent)
            {
                // Check that we are not connected to the node control if it is being reused
                bool already_connected = false;
                if (!already_connected)
                {
                    foreach (ConnectorControl cc in connectors_to)
                    {
                        if (cc.node_from == node_new)
                        {
                            already_connected = true;
                            break;
                        }
                    }
                }
                if (!already_connected)
                {
                    foreach (ConnectorControl cc in connectors_from)
                    {
                        if (cc.node_to == node_new)
                        {
                            already_connected = true;
                            break;
                        }
                    }
                }

                // Create a link to the new child
                if (!already_connected)
                {
                    ConnectorControl connector_new = new ConnectorControl(node_control_parent.scene_rendering_control);
                    connector_new.SetNodes(node_control_parent, node_new);
                    node_control_parent.scene_rendering_control.AddNewConnectorControl(connector_new);
                }

                // Choose this new node
                if (select_node)
                {
                    node_control_parent.scene_rendering_control.SetSelectedNodeControl(node_new, false);
                }
            }
        }