/* * */ //ResizePanel public void ResizePanel(VPPanel panel, Size new_size) { Size old_size = panel.Size; panel.Size = new_size; foreach (string slave in panel.Rules.Keys) { foreach (Rule rule in panel.Rules[slave]) { if (rule.Trigger == typeof(Size)) { string visual_part = ConvertToPosition(slave).First(); string view = ConvertToPosition(slave).Last(); Dictionary <object, object> args = new Dictionary <object, object>() { { "slave", (pieces.Keys.Contains(visual_part)) ? pieces[visual_part].Item1.GetPanel(view) : GetPanel(slave) }, { "master_sizes", new Tuple <Size, Size>(old_size, new_size) } }; rule.Execute(args); } } } }
/* * */ //GetPanel public VPPanel GetPanel(string name) { List <string> position = ConvertToPosition(name); Control[] subcontainers; if (position.Count() == 1 && views.ContainsKey(position[0])) { subcontainers = new VPPanel[1] { views[position[0]] }; } else if (position.Count() > 1 && views.ContainsKey(position[0])) { subcontainers = views[position[0]].Controls.Find(name, true); } else { subcontainers = new VPPanel[0]; } if (subcontainers.Count() == 1) { return((VPPanel)subcontainers[0]); } else { throw new Exception("Could not find consistent control at specified position"); } }
/* * views_names : keys = views from added visualPart, values = positions in the current visualPart * locations : keys = views from added visualPart, values = locations in the current visualPart * * create a new panel in current visualPart for each concerned view (path = position + name) */ //AddVisualPart public void AddVisualPart(string name, VisualPart visual_part, Dictionary <string, string> views_names, Dictionary <string, Point> locations) { visual_part.ChangeScaling(scaling); pieces.Add(name, new Tuple <VisualPart, HashSet <string> >(visual_part, new HashSet <string>())); foreach (string view in views_names.Keys) { List <string> position = ConvertToPosition(views_names[view]); position.Add(name); string view_container = ConvertToName(position); VPPanel container = AddPanel(view_container, locations[view], visual_part.Views[view].Mm_size); //container.BorderStyle = BorderStyle.FixedSingle;//MODIF wtf apparence bizarre? pieces[name].Item2.Add(view_container); container.Controls.Add(visual_part.Views[view]); OrderedDictionary size = new OrderedDictionary() { { "slave", null }, { "master_sizes", null }, { "axis_dependency", new Tuple <bool, bool>(true, true) }, { "axis_inversion", false } }; Action <VPPanel, Tuple <Size, Size>, Tuple <bool, bool>, bool> SizCopySizeChangeRule = visual_part.CopySizeChangeRule; AddRule(container.Name, string.Concat(view, "_" + name), SizCopySizeChangeRule, size, typeof(Size)); //MODIF desactive peut etre l'opportunite de cliquer sur l'etage, a verifier } }
//SizeDependentPositionRule /// <summary> /// The rule which change the position if the size is changed /// </summary> /// <param name="slave"></param> /// <param name="master_sizes"></param> /// <param name="axis_dependency"></param> /// <param name="axis_inversion"></param> public void SizeDependentPositionRule(VPPanel slave, Tuple<Size, Size> master_sizes, Tuple<bool, bool> axis_dependency, bool axis_inversion) { double sx = slave.Size.Width; double sy = slave.Size.Height; double lx = slave.Location.X + sx / 2; double ly = slave.Location.Y + sy / 2; double x = (master_sizes.Item2.Width / master_sizes.Item1.Width); double y = (master_sizes.Item2.Height / master_sizes.Item1.Height); if(axis_dependency.Item1) { if(axis_inversion) { ly = ly * x; } else { lx = lx * x; } } if(axis_dependency.Item2) { if(axis_inversion) { lx = lx * y; } else { ly = ly * y; } } lx = lx - sx / 2; ly = ly - sy / 2; RelocatePanel(slave, new Point(Convert.ToInt32(lx), Convert.ToInt32(ly))); }
//AddPanel /// <summary> /// Add a VPPanel in the VisualPart /// </summary> /// <param name="name">the name(exclusive) of the VPPanel to be added</param> /// <param name="location"> the location of the VPPanel in the VisualPart (unit of measurement) </param> /// <param name="size"> The size of the VPPanel to be added (unit of measurement) </param> /// <param name="color"> The color of the VPPanel to be added </param> /// <param name="is_elliptic"> Specify if the VPPanel is elliptic (true) or rectangular (false) </param> /// <returns></returns> public VPPanel AddPanel(string name, Point location, Size size, Color? color = null, bool is_elliptic = false) { List<string> position = ConvertToPosition(name); VPPanel subcontainer; if (HasSubcontainer(position)) { if (position.Count() > 1) { subcontainer = GetPanel(ConvertToName(position.Take(position.Count() - 1).ToList())); } else if (position.Count() == 1) { subcontainer = null; } else { throw new Exception("Specify a nonempty position"); } positions = AddPosition(positions, position); VPPanel new_panel = new VPPanel(); bool mouseHover = true; if (color == null) { color = SystemColors.Control; mouseHover = false; } if(subcontainer != null) { subcontainer.Controls.Add(new_panel); new_panel.Click += new EventHandler(Click); if (mouseHover) { new_panel.MouseHover += new EventHandler(MouseHover); } } else { views[name] = new_panel; ChangeConstrainingSize(); } new_panel.BackColor = (Color)color; new_panel.Mm_location = location; new_panel.Location = ScalePoint(location, scaling); new_panel.Name = name; new_panel.Mm_size = size; new_panel.Size = ScaleSize(size, scaling); if(is_elliptic) { new_panel.Shape = new EventHandler(new_panel.ShapeElliptic); } references.Add(new_panel.Name); return new_panel; } else { throw new Exception("The specified position does not contain a subcontainer in this VisualPart"); } }
/* * //MODIF on peut certainement modifier tous les ADDRULES pour qu'ils dépendent d'un code à paramètres (pcq la c'est du recopiage) */ //AddRule /// <summary> /// Add a Rule to a VPPanel, in short : when a dimension of a master VPPanel change, all of its slave must apply the related /// Rule. NONFONCTIONNAL /// </summary> /// <param name="ref_master"></param> /// <param name="ref_slave"></param> /// <param name="action"></param> /// <param name="args"></param> /// <param name="Ttrigger"></param> public void AddRule(string ref_master, string ref_slave, Delegate action, OrderedDictionary args, Type Ttrigger) { Type Ttarget = typeof(VPPanel); VPPanel master = GetPanel(ref_master); if(!master.Rules.ContainsKey(ref_slave)) { master.Rules[ref_slave] = new List<Rule>(); } master.Rules[ref_slave].Add(new Rule(action, args, Ttrigger, Ttarget)); }
//NoOverLappingRule : size changed /// <summary> /// The rule which relocate a slave if the master is resized /// </summary> /// <param name="slave"></param> /// <param name="master_sizes"></param> /// <param name="axis_dependency"></param> /// <param name="axis_inversion"></param> public void NoOverlappingRule(VPPanel slave, Tuple<Size, Size> master_sizes, Tuple<bool, bool> axis_dependency, bool axis_inversion) { int dsx = Convert.ToInt32(axis_dependency.Item1) * (master_sizes.Item2.Width - master_sizes.Item1.Width); int dsy = Convert.ToInt32(axis_dependency.Item2) * (master_sizes.Item2.Height - master_sizes.Item1.Height); RelocatePanel( slave, new Point( slave.Location.X + (axis_inversion ? dsy : dsx), slave.Location.Y + (axis_inversion ? dsx : dsy))); }
/* * master_locations : old, new * axis_dependency : x, y : refering to the master */ //NoOverlappingRule : location changed /// <summary> /// The rule which relocate a slave if the master is relocated /// </summary> /// <param name="slave"></param> /// <param name="master_locations"></param> /// <param name="axis_dependency"></param> /// <param name="axis_inversion"></param> public void NoOverlappingRule(VPPanel slave, Tuple<Point, Point> master_locations, Tuple<bool, bool> axis_dependency, bool axis_inversion) { int dlx = Convert.ToInt32(axis_dependency.Item1) * (master_locations.Item2.X - master_locations.Item1.X); int dly = Convert.ToInt32(axis_dependency.Item2) * (master_locations.Item2.Y - master_locations.Item1.Y); RelocatePanel( slave, new Point( slave.Location.X + (axis_inversion ? dly : dlx), slave.Location.Y + (axis_inversion ? dlx : dly))); }
/* * */ //CopySizeProportionRule /// <summary> /// The rule which change the size of a slave if the master size is modified (proportions) /// </summary> /// <param name="slave"></param> /// <param name="master_sizes"></param> /// <param name="axis_dependency"></param> /// <param name="axis_inversion"></param> public void CopySizeProportionRule(VPPanel slave, Tuple<Size, Size> master_sizes, Tuple<bool, bool> axis_dependency, bool axis_inversion) { double cx = Convert.ToInt32(axis_dependency.Item1) * (master_sizes.Item2.Width / master_sizes.Item1.Width); double cy = Convert.ToInt32(axis_dependency.Item2) * (master_sizes.Item2.Height / master_sizes.Item1.Height); ResizePanel( slave, new Size( Convert.ToInt32(slave.Size.Width * (axis_inversion ? cy : cx)), Convert.ToInt32(slave.Size.Height * (axis_inversion ? cx : cy)))); }
//CopySizeChangeRule /// <summary> /// The rule which change the size of a slave if the size of the master is modified /// </summary> /// <param name="slave"></param> /// <param name="master_sizes"></param> /// <param name="axis_dependency"></param> /// <param name="axis_inversion"></param> public void CopySizeChangeRule(VPPanel slave, Tuple<Size, Size> master_sizes, Tuple<bool, bool> axis_dependency, bool axis_inversion) { int dx = Convert.ToInt32(axis_dependency.Item1) * (master_sizes.Item2.Width - master_sizes.Item1.Width); int dy = Convert.ToInt32(axis_dependency.Item2) * (master_sizes.Item2.Height - master_sizes.Item1.Height); ResizePanel( slave, new Size( slave.Size.Width + (axis_inversion ? dy : dx), slave.Size.Height + (axis_inversion ? dx : dy))); }
//RemovePanel /// <summary> /// Remove the VPPanel with the name /// </summary> /// <param name="name"></param> public void RemovePanel(string name) { List<string> position = ConvertToPosition(name); List<string> container_position = position.Take(position.Count() - 1).ToList(); VPPanel container = GetPanel(ConvertToName(container_position)); container.Controls.RemoveByKey(name); references.Remove(name); if (position.Count() == 1) { views.Remove(name); } positions = RemovePosition(positions, position); }
//ReinsertPiece /// <summary> /// When a piece is displayed in a screen, the related controls are removed from the VisualPart that contained the piece /// This method adds the said removed controls in the right place anew /// </summary> /// <param name="name">the name of the piece that had been displayed</param> public void ReinsertPiece(string name) { VisualPart piece = Pieces[name].Item1; foreach(string container in Pieces[name].Item2.Keys) { VPPanel master = GetPanel(container); VPPanel slave = piece.GetPanel(Pieces[name].Item2[container]); if(!master.Controls.Contains(slave)) { master.Controls.Add(slave); } } }
/* * */ //ChangeScaling : scaling public void ChangeScaling(double scaling) { foreach (string reference in references) { VPPanel current = GetPanel(reference); current.Location = ScalePoint(current.Mm_location, scaling); current.Size = ScaleSize(current.Mm_size, scaling); } foreach (string visual_part in pieces.Keys) { VisualPart piece = pieces[visual_part].Item1; piece.ChangeScaling(scaling); } }
//CreateViews /// <summary> /// Construct as many VPPanel as the number of elements in mm_sizes, with the related dimensions /// </summary> /// <param name="mm_sizes">The sizes of the views (keys are the views names) (unit of measurement)</param> private void CreateViews(Dictionary<string, Size> mm_sizes) { this.views = new Dictionary<string, VPPanel>(); List<string> list_views = mm_sizes.Keys.ToList(); for (int i = 0; i < list_views.Count(); i++) { VPPanel new_panel = new VPPanel(); new_panel.BackColor = SystemColors.Control; new_panel.Location = new Point(0, 0); new_panel.Mm_location = new Point(0, 0); new_panel.Name = list_views[i]; new_panel.Size = mm_sizes[list_views[i]]; new_panel.Mm_size = mm_sizes[list_views[i]]; views[list_views[i]] = new_panel; positions[list_views[i]] = null; references.Add(list_views[i]); } }
//SelectPiece /// <summary> /// This method can be used to select a Component of the VisualPart, the colors will be adapted to /// have a better visualization of the selection, the selected Component will have its name stored in Pointer /// </summary> /// <param name="sender"></param> public void SelectPiece(object sender) { if(!typeof(VPPanel).IsInstanceOfType(sender)) { return; } VPPanel current_sender = (VPPanel)sender; string piece_name = ConvertToPosition(current_sender.Name).Last(); if(pieces.Keys.Contains(piece_name)) { UndoFocus(); pointer = current_sender.Name; Focus(current_sender); SearchScreen(sender); } else { SelectPiece(current_sender.Parent); } }
//RelocatePanel /// <summary> /// Relocate a VPPanel /// </summary> /// <param name="panel"></param> /// <param name="new_location"></param> public void RelocatePanel(VPPanel panel, Point new_location) { Point old_location = panel.Location; panel.Location = new_location; foreach (string slave in panel.Rules.Keys) { foreach (Rule rule in panel.Rules[slave]) { if (rule.Trigger == typeof(Point)) { Dictionary<object, object> args = new Dictionary<object, object>() { { "slave", GetPanel(slave) }, { "master_locations", new Tuple<Point, Point>(old_location, new_location) } }; rule.Execute(args); } } } }