예제 #1
0
        /// <summary>
        /// This callback function will be called immediately after the Direct3D device has
        /// been destroyed, which generally happens as a result of application termination or
        /// windowed/full screen toggles. Resources created in the OnCreateDevice callback
        /// should be released here, which generally includes all Pool.Managed resources.
        /// </summary>
        private void OnDestroyDevice(object sender, EventArgs e)
        {
            if (modelControl != null && modelControl.AirplaneModel != null)
            {
                if (MessageBox.Show("Do you want to save changes?", "Save changes?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    if (!string.IsNullOrEmpty(openFile))
                    {
                        modelControl.AirplaneModel.AirplaneControl.AircraftParameters.Save(openFile);
                    }
                }
            }
            if (modelControl != null)
            {
                modelControl.Dispose();
                modelControl = null;
            }
            if (sky != null)
            {
                if (sky.Mesh != null)
                {
                    sky.Mesh.Dispose();
                    sky.Mesh = null;
                }
                sky.Dispose();
                sky = null;
            }

            Bonsai.Objects.Textures.TextureBase.DisposeAll();
        }
예제 #2
0
        /// <summary>
        /// Creates the layout for a rule contents
        /// </summary>
        /// <param name="rule"></param>
        /// <param name="location"></param>
        private ModelControl CreateRuleLayout(Rule rule, Point location)
        {
            // Setup the rule control location and size
            ModelControl ruleControl = (ModelControl)GetBoxControl(rule);

            if (ruleControl != null)
            {
                location = new Point(location.X + 10, location.Y);
                location = SetSizeAndLocation(ruleControl, location);

                // Compute the position automatically
                location = new Point(location.X + 10, location.Y);
                foreach (RuleCondition ruleCondition in rule.RuleConditions)
                {
                    ModelControl ruleConditionControl = CreateRuleConditionLayout(ruleCondition, location);
                    if (ruleConditionControl != null)
                    {
                        location = InbedTopDown(ruleControl, ruleConditionControl, location, false);
                    }
                    location         = new Point(location.X - 10, location.Y + 20);
                    ruleControl.Size = new Size(ruleControl.Size.Width, ruleControl.Size.Height + 30);
                }

                pictureBox.Size = MaxSize(PanelSize, Size);
            }

            return(ruleControl);
        }
예제 #3
0
        private void OnFileOpenClicked(object sender, EventArgs e)
        {
            OpenFileDialog openDialog = new OpenFileDialog();

            openDialog.Filter = "RC Desk Pilot Aircraft (*.par)|*.par";
            if (openDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    ModelControl newModelControl = new ModelControl(openDialog.FileName, false);
                    if (newModelControl != null)
                    {
                        modelControl.Dispose();
                        modelControl                 = newModelControl;
                        toolbox.ModelControl         = newModelControl;
                        openFile                     = openDialog.FileName;
                        collisionPoints.ModelControl = modelControl;
                        ModelControlChanged();
                    }
                }
                catch
                {
                    MessageBox.Show("Not a valid aircraft file");
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Sets the default control size, according to its contents
        /// </summary>
        /// <param name="control"></param>
        /// <param name="location"></param>
        /// <returns>return>The location where filling should be continued</returns>
        private Point SetSizeAndLocation(ModelControl control, Point location)
        {
            // Set the control location
            control.ComputedPositionAndSize = true;
            control.Location = location;
            Point retVal = control.Location;

            // Increase control size according to title
            retVal = SetText(
                control,
                control.ModelName,
                control.Bold,
                Color.Black,
                retVal);

            // Increase control size according to comment
            ICommentable commentable = control.TypedModel as ICommentable;

            if (commentable != null)
            {
                retVal = SetText(
                    control,
                    commentable.Comment,
                    control.Italic,
                    Color.Green,
                    retVal);
            }

            // Registers the control to update the panel size
            RegisterControl(control);

            return(retVal);
        }
예제 #5
0
        /// <summary>
        /// Creates the layout for a procedure contents
        /// </summary>
        /// <param name="procedure"></param>
        /// <param name="location"></param>
        private ModelControl CreateProcedureLayout(Procedure procedure, Point location)
        {
            PanelSize = new Size(0, 0);

            // Setup the function control location and size
            ModelControl procedureControl = (ModelControl)GetBoxControl(procedure);

            location = SetSizeAndLocation(procedureControl, location);

            // Compute the position automatically
            location = new Point(20, location.Y);
            foreach (Parameter parameter in procedure.FormalParameters)
            {
                // Compute the parameter box size
                ModelControl parameterControl = (ModelControl)GetBoxControl(parameter);
                SetSizeAndLocation(parameterControl, location);
                location = InbedTopDown(procedureControl, parameterControl, location);
            }

            location = new Point(30, procedureControl.Location.Y + procedureControl.Size.Height + 10);
            foreach (Rule rule in procedure.Rules)
            {
                ModelControl ruleControl = CreateRuleLayout(rule, location);
                location = InbedTopDown(procedureControl, ruleControl, location, false);
                location = new Point(location.X - 10, location.Y + 10);
            }

            pictureBox.Size = MaxSize(PanelSize, Size);
            return(procedureControl);
        }
        protected virtual void InitializeComponent()
        {
            _classList = new ListControl {
                SelectionMode = ListSelectionMode.Single
            };
            _classList.Bounds            = new UniRectangle(20, 50, 200, 300);
            _classList.SelectionChanged += ClassListOnSelectionChanged;

            Children.Add(_classList);

            foreach (var charClass in _conf.CharacterClasses)
            {
                _classList.Items.Add(charClass);
            }

            _characterModel = new ModelControl(_iconFactory.VoxelModelManager)
            {
                Bounds         = new UniRectangle(300, 30, 230, 270),
                AlterTransform = Matrix.Identity
            };

            Children.Add(_characterModel);

            const int buttonWidth  = 212;
            const int buttomHeight = 40;

            _selectButton = new ButtonControl
            {
                Text   = "Select",
                Bounds = new UniRectangle(340, 300, buttonWidth, buttomHeight)
            };

            Children.Add(_selectButton);
        }
예제 #7
0
 /// <summary>
 /// Updates the panel size according to the control
 /// </summary>
 /// <param name="control"></param>
 /// <returns></returns>
 private void RegisterControl(ModelControl control)
 {
     PanelSize = new Size(
         Math.Max(PanelSize.Width, control.Location.X + control.Size.Width + 20),
         Math.Max(PanelSize.Height, control.Location.Y + control.Size.Height + 20)
         );
 }
 private void comboBoxVersion_SelectedIndexChanged(object sender, EventArgs e)
 {
     if (modelControl != null)
     {
         if ((comboBoxVersion.SelectedIndex == 0) && (modelControl.AirplaneModel.AirplaneControl.AircraftParameters.Version != 1.0))
         {
             if (MessageBox.Show("Are you sure you want to change to the advanced flight model? Some settings will be lost.",
                                 "Switch Flight Model", MessageBoxButtons.YesNo) == DialogResult.Yes)
             {
                 modelControl.AirplaneModel.AirplaneControl.AircraftParameters.Version = 1.0;
                 ModelControl = modelControl;
             }
             else
             {
                 comboBoxVersion.SelectedIndex = 1;
             }
         }
         else if ((comboBoxVersion.SelectedIndex == 1) && (modelControl.AirplaneModel.AirplaneControl.AircraftParameters.Version != 2.0))
         {
             if (MessageBox.Show("Are you sure you want to change to the basic flight model? Some settings will be lost.",
                                 "Switch Flight Model", MessageBoxButtons.YesNo) == DialogResult.Yes)
             {
                 modelControl.AirplaneModel.AirplaneControl.AircraftParameters.Version = 2.0;
                 ModelControl = modelControl;
             }
             else
             {
                 comboBoxVersion.SelectedIndex = 0;
             }
         }
     }
 }
예제 #9
0
 void Start()
 {
     if (IsPlayer == true)
     {
         Attributes = ModelControl.GetPlayerAttributesFromModel();
     }
 }
예제 #10
0
 void OnDestroy()
 {
     if (IsPlayer == true)
     {
         ModelControl.UpdatePlayerAttributesInModel(Attributes);
     }
 }
예제 #11
0
        private void drCounters(ModelControl control)
        {
            string modelName = "";
            int    expNumber = -1;
            IEnumerable <PointsListItem> points = null;

            control.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate()
            {
                modelName = control.ModelName;
                expNumber = control.ExperimentNumber;
                points    = control.Clone.CollectionPoints;
            }));

            string masterModelDir = clerk.GetExperimentModelDirName(modelName, expNumber);

            var bindings = from p in points
                           group p by p.MeasurId
                           into gr
                           let coords = (from p in gr select p.Coord)
                                        select new DataCollectionBindingSource
            {
                MeasureId      = gr.Key,
                Center         = FindCenter(coords),
                Points         = coords,
                AggregatedData = CreateTableFromMeasurement(masterModelDir, gr.Key),
            };

            control.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate()
            {
                ModelPlotter.DrawCounters(control, bindings);
            }));
        }
예제 #12
0
        private void drTrTimes(ModelControl control)
        {
            string modelName = "";
            int    expNumber = -1;
            IEnumerable <SectionListItem> sections = null;

            control.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate()
            {
                modelName = control.ModelName;
                expNumber = control.ExperimentNumber;
                sections  = control.Clone.TrTimeSections;
            }));

            string masterModelDir = clerk.GetExperimentModelDirName(modelName, expNumber);
            var    ds             = CreateDataSetFromGroups(masterModelDir);

            var bindings = from s in sections
                           group s by s.No
                           into gr
                           let coords = (from g in gr select new Point[] { g.FromCoord, g.ToCoord }).FirstOrDefault()
                                        select new DataCollectionBindingSource
            {
                MeasureId      = gr.Key,
                Center         = FindCenter(coords),
                Points         = coords,
                AggregatedData = ds.Tables[gr.Key.Value.ToString()],
            };

            control.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate()
            {
                ModelPlotter.DrawTrTimes(control, bindings);
            }));
        }
예제 #13
0
        public AircraftDimensionsForm(ModelControl modelControl)
        {
            this.modelControl = modelControl;
            InitializeComponent();

            if (modelControl != null)
            {
                numericUpDownWeight.Value   = (decimal)modelControl.AirplaneModel.AirplaneControl.AircraftParameters.Mass;
                numericUpDownWingArea.Value = (decimal)
                                              modelControl.AirplaneModel.AirplaneControl.AircraftParameters.WingArea * 10000;
                numericUpDownVertArea.Value = (decimal)
                                              modelControl.AirplaneModel.AirplaneControl.AircraftParameters.VerticalArea * 10000;
                numericUpDownWingSpan.Value = (decimal)(200 *
                                                        modelControl.AirplaneModel.AirplaneControl.AircraftParameters.WingCenter.Y *
                                                        modelControl.AirplaneModel.AirplaneControl.AircraftParameters.WingSpanFactor);
            }
            if (modelControl.AirplaneModel.AirplaneControl.AircraftParameters.Version == 1.0)
            {
                labelWingCenter.Visible         = false;
                vectorControlWingCenter.Visible = false;
                labelPropCenter.Visible         = false;
                vectorControlPropCenter.Visible = false;
                numericUpDownWingSpan.Visible   = false;
                labelWingSpan.Visible           = false;
                labelWingSpanCm.Visible         = false;
                labelWingSpanInch.Visible       = false;
            }
            else
            {
                Program.Instance.CursorVisible  = true;
                Program.Instance.Cursor2Visible = true;
                vectorControlWingCenter.Vector  = FlightModelWind.ToDirectX(modelControl.AirplaneModel.AirplaneControl.AircraftParameters.WingCenter);
                vectorControlPropCenter.Vector  = FlightModelWind.ToDirectX(modelControl.AirplaneModel.AirplaneControl.AircraftParameters.PropCenter);
            }
        }
예제 #14
0
    private void LoadAggregate()
    {
        ///////////////////////////////////////////////////////
        //Local Variables

        MainAggregate aggregate;

        BinaryFormatter formatter = new BinaryFormatter();

        FileStream file;

        string filePath = "";

        ///////////////////////////////////////////////////////

        filePath = CheckIfFileExists();

        if (filePath == null)
        {
            return;
        }

        file      = File.Open(filePath, FileMode.Open);
        aggregate = (MainAggregate)formatter.Deserialize(file);
        file.Close();

        ModelControl.UpdateModel(aggregate);
    }
예제 #15
0
        /// <summary>
        /// Creates the layout for a range contents
        /// </summary>
        /// <param name="range"></param>
        /// <param name="location"></param>
        // ReSharper disable once UnusedMethodReturnValue.Local
        private ModelControl CreateRangeLayout(Range range, Point location)
        {
            // Setup the rule control location and size
            ModelControl rangeControl = (ModelControl)GetBoxControl(range);

            if (rangeControl != null)
            {
                location = new Point(location.X + 10, location.Y);
                location = SetSizeAndLocation(rangeControl, location);

                // Compute the position automatically
                location = new Point(location.X + 10, location.Y);
                foreach (EnumValue value in range.SpecialValues)
                {
                    ModelControl valueControl = (ModelControl)GetBoxControl(value);
                    location = SetSizeAndLocation(valueControl, location);
                    if (valueControl != null)
                    {
                        location = InbedTopDown(rangeControl, valueControl, location, false);
                    }
                    location          = new Point(location.X, location.Y + 10);
                    rangeControl.Size = new Size(rangeControl.Size.Width, rangeControl.Size.Height + 20);
                }

                pictureBox.Size = MaxSize(PanelSize, Size);
            }

            return(rangeControl);
        }
예제 #16
0
 // Use this for initialization
 void Start()
 {
     m_ModelControl = GameObject.Find("Scenes_Control").GetComponent <ModelControl>();
     m_ModelControl.m_ButtonOK.onClick.AddListener(delegate() { ButtonOnClick_ClosePanel(m_ModelControl.m_UiPanel); });
     m_ModelControl.m_ButtonOK2.onClick.AddListener(delegate() { ButtonOnClick_ClosePanel(m_ModelControl.m_UiPanel2); });
     m_ModelControl.m_ButtonImage.onClick.AddListener(delegate() { ButtonOnClick_ShowData(0); });
     m_ModelControl.m_ButtonImage2.onClick.AddListener(delegate() { ButtonOnClick_ShowData(1); });
 }
예제 #17
0
 void Start()
 {
     selectmodel   = GameObject.Find("UIManager").GetComponent <SelectedModel>();
     modelcontrol  = GameObject.Find("Main Camera").GetComponent <ModelControl>();
     rotationto    = GameObject.Find("Heart").GetComponent <RotationTo>();
     scale         = GameObject.Find("Heart").GetComponent <Scale>();
     writtingboard = GameObject.Find("WrittingBoard").GetComponent <WrittingBoard>();
 }
예제 #18
0
    private void CheckForMainInputSettings()
    {
        if (MainInputSettings != null)
        {
            return;
        }

        MainInputSettings = ModelControl.GetInputSettingsFromModel();
    }
    void GhostMove()
    {
        TargetMoveIndex = PointsTools.Instance.GetMoveDir(transform, TargetMoveIndex, Clockwise);
        ModelControl.Move();

        int tragetIndex = Clockwise ? TargetMoveIndex + 1 : TargetMoveIndex;

        transform.position = Vector3.MoveTowards(transform.position, PointsTools.Instance.GetPointPos(tragetIndex), Time.deltaTime * GhostSpeed);
    }
예제 #20
0
        /// <summary>
        /// This event will be fired immediately after the Direct3D device has been
        /// created, which will happen during application initialization and windowed/full screen
        /// toggles. This is the best location to create Pool.Managed resources since these
        /// resources need to be reloaded whenever the device is destroyed. Resources created
        /// here should be released in the Disposing event.
        /// </summary>
        private void OnCreateDevice(object sender, DeviceEventArgs e)
        {
            // Initialize the stats font
            //statsFont = ResourceCache.GetGlobalInstance().CreateFont(e.Device, 15, 0, FontWeight.Bold, 1, false, CharacterSet.Default,
            //    Precision.Default, FontQuality.Default, PitchAndFamily.FamilyDoNotCare | PitchAndFamily.DefaultPitch
            //    , "Arial");
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");

            SoundManager.Initialize(Framework.Instance.Window);
            inputManager = new Bonsai.Input.InputManager(Framework.Instance.Window);

            transparentObjectManager = new TransparentObjectManager();
            weather = new Weather(this);

            //modelControl = new ModelControl("Data/cessna/cessna.par");
            modelControl = new ModelControl();

            rotationAxisMesh = new LineMesh();

            sky = new GameObject();
            DomeMesh skyDome = new DomeMesh(5000, 10, 16);

            skyDome.Texture = new Bonsai.Objects.Textures.TextureBase("data\\sky2.JPG");
            sky.Position    = new Vector3(0, -5f, 0);
            sky.Mesh        = skyDome;

            scenery = new GameObject();
            SquareMesh sceneryMesh = new SquareMesh(5000, 10, 10, 1000f);

            sceneryMesh.Texture  = new Bonsai.Objects.Textures.TextureBase("data\\scenery\\default\\grass1.jpg");
            scenery.Mesh         = sceneryMesh;
            scenery.Position     = new Vector3(0, -5f, 0);
            scenery.RotateXAngle = (float)Math.PI / 2;

            cameraEditor      = new CameraBase("ObserverCamera");
            cameraEditor.Near = 0.05f;

            cameraPilot          = new ObserverCamera("PilotCamera", modelControl.AirplaneModel);
            cameraPilot.LookFrom = new Vector3(5f, -3.3f, 5f);

            //camera.LookAt = modelControl.AirplaneModel.Position;
            //camera.LookFrom = modelControl.AirplaneModel.Position + new Vector3(cameraDistance, 0f, 0f);
            //camera.AutoZoom = true;
            cameraEditor.AspectRatio = (float)(e.BackBufferDescription.Width) / e.BackBufferDescription.Height;
            cameraPilot.AspectRatio  = (float)(e.BackBufferDescription.Width) / e.BackBufferDescription.Height;


            Framework.Instance.CurrentCamera = cameraEditor;

            sun       = new DirectionalLight(new Vector3(-0.5f, -0.707f, 0.5f));
            sun.Color = System.Drawing.Color.FromArgb(148, 148, 148);

            collisionPoints = new CollisionPoints();

            cursor3d  = new Cursor3d();
            cursor3d2 = new Cursor3d();
        }
예제 #21
0
    void Awake()
    {
        InputMove = GetComponent <InputMove>();

        GameController = GameObject.FindWithTag(TagKeys.MAIN_CONTROLLER_KEY);
        GUIController  = GameObject.FindWithTag(TagKeys.GUI_CONTROLLER_KEY);
        MessageWindow  = GameObject.FindWithTag(TagKeys.MESSAGE_WINDOW_KEY);

        MainInputSettings = ModelControl.GetInputSettingsFromModel();
    }
예제 #22
0
        public virtual void InitializeComponent()
        {
            Children.Clear();

            _ingredientsRect = new RectangleF(240, 275, 360, 42);

            _recipesList = new ListControl {
                SelectionMode = ListSelectionMode.Single
            };
            _recipesList.Bounds            = new UniRectangle(20, 50, 200, 300);
            _recipesList.SelectionChanged += RecipesListOnSelectionChanged;

            foreach (var recipe in _conf.Recipes.Where(r => r.ContainerBlueprintId == 0))
            {
                _recipesList.Items.Add(recipe);
            }

            Children.Add(_recipesList);

            // cells

            _resultModel = new ModelControl(_iconFactory.VoxelModelManager)
            {
                Bounds = new UniRectangle(300, 10, 230, 230)
            };

            Children.Add(_resultModel);

            _ingredientCells = new List <InventoryCell>();
            for (int i = 0; i < 6; i++)
            {
                var cell = new InventoryCell(null, _iconFactory, new Vector2I(), _inputsManager)
                {
                    DrawIconsGroupId      = 5,
                    DrawIconsActiveCellId = 6,
                    IsVisible             = false
                };

                _ingredientCells.Add(cell);
                Children.Add(cell);
            }

            // craft button

            const int buttonWidth  = 212;
            const int buttomHeight = 40;

            _craftButton = new ButtonControl
            {
                Text   = "Craft",
                Bounds = new UniRectangle(340, 300, buttonWidth, buttomHeight)
            };

            Children.Add(_craftButton);
        }
예제 #23
0
        public void CopyToMaster(ModelControl control)
        {
            if (control.Clone != null)
            {
                MasterModel            = control.Clone as ModelControl;
                IsCounterButtonEnabled = (MasterModel.DataContext as Experiment).Data.IsCountersEvaluationEnabled;
                IsTrTimesButtonEnabled = (MasterModel.DataContext as Experiment).Data.IsTravelTimesEvaluationEnabled;

                //DrawControl(control);
            }
        }
예제 #24
0
        private int roleType = -1;          //先暂时限制下

        public void CreateRole(int roleType, ModelControl loadInitCallBack)
        {
            this.roleType = roleType;
            vo            = new DisplayVo();
            vo.Type       = DisplayType.ROLE_MODE;
            var _SysRoleBaseInfoVo = BaseDataMgr.instance.GetSysRoleBaseInfo((uint)roleType);

            vo.ClothUrl       = "Model/Role/" + _SysRoleBaseInfoVo.Model + "/Model/" + _SysRoleBaseInfoVo.Model + ".assetbundle";
            this.modelControl = loadInitCallBack;
            SetVo(vo);
        }
예제 #25
0
    public void CheckForPlayerAttributes()
    {
        if (Attributes != null)
        {
            return;
        }

        if ((IsPlayer == true) && (Attributes == null))
        {
            Attributes = ModelControl.GetPlayerAttributesFromModel();
        }
    }
예제 #26
0
    public AbstractItemAI GetItem(int index)
    {
        if (IndexWithinBounds(index) == true)
        {
            return(ModelControl.GetItemListFromModel()[index]);
        }

        else
        {
            return(null);
        }
    }
예제 #27
0
        private void LoadModelControl()
        {
            var net = VissimSingleton.Instance.Net;

            if (modelCanvas1 == null)
            {
                modelCanvas1 = new ModelControl();
                net.Wrap().Draw(modelCanvas1.cnvModel, System.Windows.SystemColors.WindowTextBrush);
            }

            ccControlsHost.Content = modelCanvas1;
        }
예제 #28
0
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var text = DisplayIdBox.Text;
            int displayId;

            if (int.TryParse(text, out displayId) == false)
            {
                return;
            }

            ModelControl.SetCreatureDisplayEntry(displayId);
        }
예제 #29
0
        public virtual void InitializeComponent()
        {
            Children.Clear();

            _recipesList = new ListControl {
                SelectionMode = ListSelectionMode.Single
            };
            _recipesList.Bounds            = new UniRectangle(200, 200, 200, 120);
            _recipesList.SelectionChanged += RecipesListOnSelectionChanged;

            _hostModel = new ModelControl(_iconFactory.VoxelModelManager)
            {
                Bounds = new UniRectangle(20, 20, 210, 170)
            };
            _hostModel.AlterTransform = Matrix.Identity;

            Children.Add(_hostModel);


            // craft button

            const int buttonWidth  = 185;
            const int buttomHeight = 50;

            _craftButton = new ButtonControl
            {
                Text   = "Craft",
                Bounds = new UniRectangle(244, 330, buttonWidth, buttomHeight)
            };

            _resultModel = new ModelControl(_iconFactory.VoxelModelManager)
            {
                Bounds = new UniRectangle(210, 20, 190, 120)
            };

            _hostModel.Bounds.Size.X = 200;

            _ingredientsRect = new RectangleF(200, 145, 200, 42);

            _ingredientCells = new List <InventoryCell>();
            for (int i = 0; i < 6; i++)
            {
                var cell = new InventoryCell(null, _iconFactory, new Vector2I(), _inputsManager)
                {
                    DrawIconsGroupId      = 5,
                    DrawIconsActiveCellId = 6,
                    IsVisible             = false
                };

                _ingredientCells.Add(cell);
            }
        }
예제 #30
0
        public static void DrawLinks(ModelControl control, IEnumerable <LinkItem> links)
        {
            control.HasNetwork = control.Clone.HasNetwork = true;

            var canvas1 = control.cnvModel;
            var canvas2 = control.Clone.cnvModel;

            foreach (var link in links)
            {
                AddLinkToCanvas(canvas1, link);
                AddLinkToCanvas(canvas2, link);
            }
        }