using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WebWindowComplex.Json; using static WebWindowComplex.Json.WindowConst; namespace WebWindowComplex.Models { public class SplitDimension:AreaDimension { #region Public Constructors public SplitDimension(double dDimension, MeasureTypes MeasureType, bool bIsRelative, Split Parent, bool IsVertList):base(dDimension, MeasureType) { m_dDimension = dDimension; m_bIsRelative = bIsRelative; m_Parent = Parent; m_bIsVertListDim = IsVertList; } #endregion Public Constructors #region Public Properties public bool bIsRelative { get { return m_bIsRelative; } } public bool bIsVertListDim { get { return m_bIsVertListDim; } } public override double dDimension { get { return m_dDimension; } set { double dimensionTot = 0; List dimensions = new List(); Frame frame = m_Parent.ParentWindow.AreaList.FirstOrDefault()?? new Frame(null, Parent.ParentWindow); if (bIsVertListDim) { dimensions = m_Parent.SplitVertList; dimensionTot = CalculateWidthSplitGroup(frame, frame.DimensionList.Where(x => x.sName == "Width").First().dDimension, new AreaFound(-1, false)).m_Dimension; } else { dimensions = m_Parent.SplitHorizList; //dimensionTot = (CalculateHeightSplitGroup(m_Parent, HeightTot(), new AreaFound(-1, false))).m_Dimension; dimensionTot = (CalculateHeightSplitGroup(frame, frame.HeightFrame(), new AreaFound(-1, false))).m_Dimension; } double valMinAbsolute = 100; double valMaxAbsolute = dimensionTot - valMinAbsolute * (dimensions.Count - 1); bool valueAccept = false; switch (MeasureType) { case MeasureTypes.ABSOLUTE: { valueAccept = (value < valMaxAbsolute && value > valMinAbsolute) ? true : false; break; } case MeasureTypes.PROPORTIONAL: { valMaxAbsolute = 20; valueAccept = (value >= 1) ? true : false; break; } case MeasureTypes.PERCENTAGE: { valMaxAbsolute = valMaxAbsolute / dimensionTot * 100; valMinAbsolute = valMinAbsolute / dimensionTot * 100; valueAccept = (value < valMaxAbsolute && value > valMinAbsolute) ? true : false; break; } } if (valueAccept) { List absoluteValList = new List(); AreaDimension ad = new AreaDimension(dDimension, SelMeasureType); List adList = new List(); foreach (var it in dimensions) { adList.Add(new AreaDimension(it.dDimension, it.SelMeasureType)); } foreach (var item in dimensions) { absoluteValList.Add(item.CalculateAbsoluteValue(adList, dimensionTot)); } int nIndex = dimensions.IndexOf(this); int proportionalCount = dimensions.Where(x => x.MeasureType.Equals(MeasureTypes.PROPORTIONAL)).ToList().Count; int percentageCount = dimensions.Where(x => x.MeasureType.Equals(MeasureTypes.PERCENTAGE)).ToList().Count; // Le dimensioni sono solo in proporzionale if (proportionalCount == absoluteValList.Count) { m_dDimension = value; } // Le dimensioni sono solo in percentuale else if (percentageCount == dimensions.Count) { if (value < dDimension) { // L'anta modificata non è l'ultima if (nIndex < dimensions.Count - 1) dimensions[nIndex + 1].SetDimension(dimensions[nIndex + 1].dDimension + (m_dDimension - value)); else if (dimensions.Count > 1) dimensions[nIndex - 1].SetDimension(dimensions[nIndex - 1].dDimension + (m_dDimension - value)); else { m_dDimension = 100; return; } } else { double dRes = value; // se non ultima anta if (nIndex < dimensions.Count - 1) { for (var nInd = 0; nInd <= nIndex - 1; nInd++) dRes += dimensions[nInd].dDimension; dRes = (100 - dRes) / (dimensions.Count - nIndex - 1); for (var Ind = nIndex + 1; Ind <= dimensions.Count - 1; Ind++) dimensions[Ind].SetDimension(dRes); } // se ultima anta else if (dimensions.Count > 1) { if (dimensions.Count > 2) { for (var Ind = 0; Ind <= nIndex - 2; Ind++) dRes += dimensions[Ind].dDimension; } dRes = (100 - dRes); dimensions[nIndex - 1].SetDimension(dRes); } else { m_dDimension = 100; return; } } m_dDimension = value; } // Le dimensioni sono miste o solo in assoluto else { double valueInAbsolute = 0; switch (MeasureType) { case MeasureTypes.ABSOLUTE: { valueInAbsolute = value; break; } case MeasureTypes.PROPORTIONAL: { var pesi = value + dimensions .Where(x => x.MeasureType.Equals(MeasureTypes.PROPORTIONAL) && !x.Equals(this)) .Sum(x => x.m_dDimension); valueInAbsolute = dimensionTot / pesi * value; break; } case MeasureTypes.PERCENTAGE: { valueInAbsolute = (value / 100) * dimensionTot; break; } } if (value < dDimension) { // L'anta modificata non è l'ultima if (nIndex < absoluteValList.Count - 1) { absoluteValList[nIndex + 1] = absoluteValList[nIndex + 1] + (absoluteValList[nIndex] - valueInAbsolute); absoluteValList[nIndex] = valueInAbsolute; } // L'anta modificata è l'ultima else if (dimensions.Count > 1) { absoluteValList[nIndex - 1] = absoluteValList[nIndex - 1] + (absoluteValList[nIndex] - valueInAbsolute); absoluteValList[nIndex] = valueInAbsolute; } } else { // L'anta modificata non è l'ultima if (nIndex < absoluteValList.Count - 1) { absoluteValList[nIndex + 1] = absoluteValList[nIndex + 1] - (valueInAbsolute - absoluteValList[nIndex]); absoluteValList[nIndex] = valueInAbsolute; } // L'anta modificata è l'ultima else if (dimensions.Count > 1) { absoluteValList[nIndex - 1] = absoluteValList[nIndex - 1] - (valueInAbsolute - absoluteValList[nIndex]); absoluteValList[nIndex] = valueInAbsolute; } } if (MeasureType.Equals(MeasureTypes.PROPORTIONAL)) m_dDimension = value; for (int i = 0; i < absoluteValList.Count; i++) { var item = dimensions.ElementAt(i); item.SetDimension(ad.ConvertIn(adList, absoluteValList[i], (MeasureTypes)item.SelMeasureTypeIndex, dimensionTot)); } } for (int i = 0; i < m_Parent.AreaList.Count; i++) { if (m_Parent.SplitHorizList.Count > 0 && i < m_Parent.SplitHorizList.Count) m_Parent.AreaList.ElementAt(i).SearchAreaList(m_Parent.AreaList.ElementAt(i), m_Parent.SplitHorizList.ElementAt(i).dDimension, "Height"); if (m_Parent.SplitVertList.Count > 0 && i < m_Parent.SplitVertList.Count) m_Parent.AreaList.ElementAt(i).SearchAreaList(m_Parent.AreaList.ElementAt(i), m_Parent.SplitVertList.ElementAt(i).dDimension, "Width"); } } } } public Split Parent { get { return m_Parent; } set { m_Parent = value; } } public override int SelMeasureTypeIndex { get { return (int)m_SelMeasureType; } set { if (m_SelMeasureType != (MeasureTypes)value) { MeasureTypes newType = (MeasureTypes)value; List splitList = new List(); if(m_Parent.ParentWindow.AreaList.FirstOrDefault() != null) { Frame frame = m_Parent.ParentWindow.AreaList.FirstOrDefault()!; double tot = 0; if (bIsVertListDim) { splitList = m_Parent.SplitVertList; tot = CalculateWidthSplitGroup(frame, frame.DimensionList.Where(x => x.sName == "Width").First().dDimension, new AreaFound(-1, false)).m_Dimension; } else { splitList = m_Parent.SplitHorizList; tot = (CalculateHeightSplitGroup(frame, frame.HeightFrame(), new AreaFound(-1, false))).m_Dimension; } AreaDimension ad = new AreaDimension(dDimension, SelMeasureType); List adList = new List(); foreach (var it in splitList) { adList.Add(new AreaDimension(it.dDimension, it.SelMeasureType)); } m_dDimension = ad.ConvertDimension(adList, m_SelMeasureType, newType, tot, splitList.IndexOf(this)); m_SelMeasureType = (MeasureTypes)value; } } } } #endregion Public Properties #region Public Methods public SplitDimension Copy() { SplitDimension newSplitDim = new SplitDimension(dDimension, MeasureType, bIsRelative, m_Parent, bIsVertListDim); return newSplitDim; } #endregion Public Methods #region Internal Methods /// /// Metodo per calcolare larghezza intero split group /// /// area di partenza /// larghezza di partenza /// area di ritorno /// internal AreaFound CalculateWidthSplitGroup(Area area, double width, AreaFound res) { for (int i = 0; i < area.AreaList.Count; i++) { if (area.Equals(m_Parent)) { res.m_Dimension = width; res.m_Found = true; return res; } Area item = area.AreaList[i]; if (area is Split) { Split split = (Split)area; if(split.SplitVertList.Count > 0) { int index = i; if (split.SelSplitShape is SplitShapes.GRID) index = i % split.SplitHorizList.Count; switch (split.SplitVertList.ElementAt(index).SelMeasureType) { case MeasureTypes.ABSOLUTE: { res = CalculateWidthSplitGroup(item, split.SplitVertList.ElementAt(index).dDimension, res); break; } case MeasureTypes.PROPORTIONAL: { AreaDimension ad = new AreaDimension(split.SplitVertList.ElementAt(index).dDimension, split.SplitVertList.ElementAt(index).SelMeasureType); List adList = new List(); foreach (var it in split.SplitVertList) { adList.Add(new AreaDimension(it.dDimension, it.SelMeasureType)); } res = CalculateWidthSplitGroup(item, ad.ConvertFromPropVal(adList, MeasureTypes.ABSOLUTE, width), res); break; } case MeasureTypes.PERCENTAGE: { res = CalculateWidthSplitGroup(item, split.SplitVertList.ElementAt(index).dDimension * width / 100, res); break; } } if (res.m_Dimension != -1 && res.m_Found) return res; } else { res = CalculateWidthSplitGroup(item, width, res); if (res.m_Dimension != -1 && res.m_Found) return res; } } else if (area is Sash) { Sash sash = (Sash)area; switch (sash.SashList.ElementAt(i).SelMeasureType) { case MeasureTypes.ABSOLUTE: { res = CalculateWidthSplitGroup(item, sash.SashList.ElementAt(i).dDimension, res); break; } case MeasureTypes.PROPORTIONAL: { AreaDimension ad = new AreaDimension(sash.SashList.ElementAt(i).dDimension, sash.SashList.ElementAt(i).SelMeasureType); List adList = new List(); foreach (var it in sash.SashList) { adList.Add(new AreaDimension(it.dDimension, it.SelMeasureType)); } res = CalculateWidthSplitGroup(item, ad.ConvertFromPropVal(adList, MeasureTypes.ABSOLUTE, width), res); break; } case MeasureTypes.PERCENTAGE: { res = CalculateWidthSplitGroup(item, sash.SashList.ElementAt(i).dDimension * width / 100, res); break; } } if (res.m_Dimension != -1 && res.m_Found) return res; } else { res = CalculateWidthSplitGroup(item, width, res); if (res.m_Dimension != -1 && res.m_Found) return res; } } return res; } /// /// Metodo per calcolare altezza intero split group /// /// area di partenza /// altezza di partenza /// area di ritorno /// internal AreaFound CalculateHeightSplitGroup(Area area, double height, AreaFound res) { for (int i = 0; i < area.AreaList.Count; i++) { if (area.Equals(m_Parent)) { res.m_Dimension = height; res.m_Found = true; return res; } Area item = area.AreaList[i]; if (area is Split) { Split split = (Split)area; if (split.SplitHorizList.Count > 0) { int index = i; if (split.SelSplitShape is SplitShapes.GRID) index = i % split.SplitHorizList.Count; switch (split.SplitHorizList.ElementAt(index).SelMeasureType) { case MeasureTypes.ABSOLUTE: { double heightItemGroup = split.SplitHorizList.ElementAt(index).dDimension; res = CalculateHeightSplitGroup(item, heightItemGroup, res); break; } case MeasureTypes.PROPORTIONAL: { AreaDimension ad = new AreaDimension(split.SplitHorizList.ElementAt(index).dDimension, split.SplitHorizList.ElementAt(index).SelMeasureType); List adList = new List(); foreach (var it in split.SplitHorizList) { adList.Add(new AreaDimension(it.dDimension, it.SelMeasureType)); } double heightItemGroup = ad.ConvertFromPropVal(adList, MeasureTypes.ABSOLUTE, height); res = CalculateHeightSplitGroup(item, heightItemGroup, res); break; } case MeasureTypes.PERCENTAGE: { double heightItemGroup = split.SplitHorizList.ElementAt(index).dDimension * height / 100; res = CalculateHeightSplitGroup(item, heightItemGroup, res); break; } } if (res.m_Dimension != -1 && res.m_Found) return res; } else { res = CalculateHeightSplitGroup(item, height, res); if (res.m_Dimension != -1 && res.m_Found) return res; } } else { res = CalculateHeightSplitGroup(item, height, res); if (res.m_Dimension != -1 && res.m_Found) return res; } } return res; } internal JsonSplitDimension Serialize() { JsonSplitDimension JsonSplitDimension = new JsonSplitDimension(m_bIsRelative, m_dDimension, MeasureType); return JsonSplitDimension; } internal void SetIsRelative(bool value) { m_bIsRelative = value; } internal void SetIsVertListDim(bool value) { m_bIsVertListDim = value; } internal void SetMeasureType(MeasureTypes value) { m_SelMeasureType = value; } internal void SetSelMeasureType(MeasureTypes value) { if (m_SelMeasureType != (MeasureTypes)value) { MeasureTypes newType = (MeasureTypes)value; if(m_Parent.ParentWindow.AreaList.FirstOrDefault() != null) { Frame frame = m_Parent.ParentWindow.AreaList.FirstOrDefault()!; double dimSplitGroup = 0; if (bIsVertListDim) { dimSplitGroup = (CalculateWidthSplitGroup(frame, frame.DimensionList.Where(x => x.sName == "Width").First().dDimension, new AreaFound(-1, false))).m_Dimension; AreaDimension ad = new AreaDimension(dDimension, SelMeasureType); List newDimensions = new List(); foreach (var item in m_Parent.SplitVertList) { newDimensions.Add(new AreaDimension(item.dDimension, item.SelMeasureType)); } m_dDimension = ad.ConvertDimension(newDimensions, m_SelMeasureType, newType, dimSplitGroup, m_Parent.SplitVertList.IndexOf(this)); if (newType is MeasureTypes.PROPORTIONAL) { for (int i = 0; i < m_Parent.SplitVertList.Count; i++) { m_Parent.SplitVertList.ElementAt(i).SetDimension(newDimensions.ElementAt(i).dDimension); } } } else { //tot = (CalculateHeightSplitGroup(m_Parent, HeightTot(), new AreaFound(-1, false))).m_Dimension; dimSplitGroup = (CalculateHeightSplitGroup(frame, frame.HeightFrame(), new AreaFound(-1, false))).m_Dimension; AreaDimension ad = new AreaDimension(dDimension, SelMeasureType); List newDimensions = new List(); foreach (var item in m_Parent.SplitHorizList) { newDimensions.Add(new AreaDimension(item.dDimension, item.SelMeasureType)); } m_dDimension = ad.ConvertDimension(newDimensions, m_SelMeasureType, newType, dimSplitGroup, m_Parent.SplitHorizList.IndexOf(this)); if(newType is MeasureTypes.PROPORTIONAL) { for(int i = 0; i < m_Parent.SplitHorizList.Count; i++) { m_Parent.SplitHorizList.ElementAt(i).SetDimension(newDimensions.ElementAt(i).dDimension); } } } m_SelMeasureType = (MeasureTypes)value; } } } #endregion Internal Methods #region Private Fields private bool m_bIsRelative = false; private bool m_bIsVertListDim = false; // reference private Split m_Parent; #endregion Private Fields } public class AreaFound { public AreaFound(double dimension, bool found) { m_Dimension = dimension; m_Found = found; } public double m_Dimension { get; set; } = -1; public bool m_Found { get; set; } = false; } }