using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WebWindowTest.Json; using static WebWindowTest.Json.WindowConst; namespace WebWindowTest.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 = null; Frame frame = m_Parent.ParentWindow.AreaList.FirstOrDefault(); 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 MeasureTypes MeasureType //{ // get // { // return m_SelMeasureType; // } //} //public List MeasureTypeList //{ // get // { // return m_MeasureTypeList; // } //} //public MeasureTypes SelMeasureType //{ // get // { // return m_SelMeasureType; // } // set // { // m_SelMeasureType = value; // } //} public override int SelMeasureTypeIndex { get { return (int)m_SelMeasureType; } set { if (m_SelMeasureType != (MeasureTypes)value) { MeasureTypes newType = (MeasureTypes)value; List splitList = 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 ///// ///// Metodo per convertire la dimensione dal vecchio tipo al nuovo tipo ///// ///// Vecchio tipo ///// Nuovo tipo ///// //public double ConvertDimension(MeasureTypes oldType, MeasureTypes newType, double widthTot, List splitList) //{ // switch (oldType) // { // case MeasureTypes.ABSOLUTE: // { // if (newType.Equals(MeasureTypes.PERCENTAGE)) // { // //return Double.Round((m_dDimension / m_Parent.Width) * 100, 1); // return (m_dDimension / widthTot) * 100; // } // else // { // return CalculatePropVal(widthTot, splitList); // } // } // case MeasureTypes.PROPORTIONAL: // { // if (newType.Equals(MeasureTypes.ABSOLUTE)) // { // //return Double.Round(ConvertFromPropVal(newType), 2); // return ConvertFromPropVal(newType, widthTot, splitList); // } // else // { // //return Double.Round(ConvertFromPropVal(newType), 1); // return ConvertFromPropVal(newType, widthTot, splitList); // } // } // case MeasureTypes.PERCENTAGE: // { // if (newType.Equals(MeasureTypes.ABSOLUTE)) // { // //return Double.Round((m_dDimension * m_Parent.Width) / 100, 2); // return (m_dDimension * widthTot) / 100; // } // else // { // return CalculatePropVal(widthTot, splitList); // } // } // } // return -1; //} 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; } ///// ///// Calcolo MCD ///// ///// ///// ///// //internal static double CalculateMCD(double a, double b) //{ // while (b >= 0.01) // { // double temp = b; // b = a % b; // a = temp; // } // //return Double.Round(a,2); // return a; //} ///// ///// Metodo per ricalcolare i valori proporzionali a causa della modifica di uno ///// ///// //internal double CalculatePropVal(double widthTot, List splitList) //{ // if (splitList.Where(m => m.MeasureType.Equals(MeasureTypes.PROPORTIONAL)).ToList().Count == 0) // { // return 1; // } // List absoluteValue = new List(); // foreach (var item in splitList) // { // absoluteValue.Add(item.CalculateAbsoluteValue(widthTot, splitList)); // } // for (int i = 0; i < splitList.Count; i++) // { // if (!splitList.ElementAt(i).Equals(this) && // splitList.ElementAt(i).MeasureType.Equals(MeasureTypes.PROPORTIONAL)) // { // int nIndex = splitList.IndexOf(this); // if (absoluteValue.ElementAt(nIndex) <= absoluteValue.ElementAt(i)) // { // var mcd = CalculateMCD(absoluteValue.ElementAt(nIndex), absoluteValue.ElementAt(i)); // splitList.ElementAt(i).m_dDimension = absoluteValue.ElementAt(i) / mcd; // m_dDimension = absoluteValue.ElementAt(nIndex) / mcd; // } // else // { // var mcd = CalculateMCD(absoluteValue.ElementAt(nIndex), absoluteValue.ElementAt(i)); // splitList.ElementAt(i).m_dDimension = absoluteValue.ElementAt(i) / mcd; // m_dDimension = absoluteValue.ElementAt(nIndex) / mcd; // } // break; // } // } // return m_dDimension; //} ///// ///// Metodo per trasformare una dimensione in valore assoluto rispetto alla larghezza totale ///// ///// Larghezza totale ///// //internal double CalculateAbsoluteValue(double widthTot, List splitList) //{ // switch (MeasureType) // { // case MeasureTypes.ABSOLUTE: // { // //return Double.Round(dDimension, 2); // return dDimension; // } // case MeasureTypes.PROPORTIONAL: // { // //return Double.Round(Proportional2AbsolutVal(), 2); // return Proportional2AbsoluteVal(widthTot, splitList); // } // case MeasureTypes.PERCENTAGE: // { // //return Double.Round((dDimension / 100) * widthTot, 1); // return (dDimension / 100) * widthTot; // } // } // return 0; //} ///// ///// Metodo per convertire una dimensione da un valore assoluto al suo rispettivo tipo ///// ///// Valore assoluto ///// Tipo di misura della dimensione ///// Larghezza totale ///// //internal double ConvertIn(double absoluteVal, MeasureTypes type, double widthTot, List splitList) //{ // switch (type) // { // case MeasureTypes.ABSOLUTE: // { // return absoluteVal; // } // case MeasureTypes.PROPORTIONAL: // { // return Proportional2AbsoluteVal(widthTot, splitList); // } // case MeasureTypes.PERCENTAGE: // { // return (absoluteVal / widthTot) * 100; // } // } // return -1; //} ///// ///// Metodo per convertire da misura proporzionale a misura assoluta o percentuale ///// ///// ///// //internal double ConvertFromPropVal(MeasureTypes newType, double widthTot, List splitList) //{ // double tot = widthTot; // //Somma misura non proporzionali // double sumNotProp = splitList // .Where(m => m.MeasureType != MeasureTypes.PROPORTIONAL && !m.Equals(this)) // .Sum(m => m.CalculateAbsoluteValue(tot, splitList)); // //Calcolo residuo // double res = tot - sumNotProp; // if (res < 0) res = 0; // //Misure proporzionali // var proportionalList = splitList // .Where(m => m.SelMeasureType == MeasureTypes.PROPORTIONAL) // .ToList(); // double sumPesi = proportionalList.Sum(p => p.dDimension); // if (sumPesi == 0) sumPesi = 1; // if (newType.Equals(MeasureTypes.ABSOLUTE)) // { // return res / sumPesi * dDimension; // } // else // { // return (res / sumPesi * dDimension) / tot * 100; // } //} ///// ///// Metodo per trasformare il valore proporzionale in assoluto ///// ///// //internal double Proportional2AbsoluteVal(double widthTot, List splitList) //{ // double tot = widthTot; // //Somma misura non proporzionali // double sumNotProp = splitList // .Where(m => m.MeasureType != MeasureTypes.PROPORTIONAL) // .Sum(m => m.CalculateAbsoluteValue(tot, splitList)); // //Calcolo residuo // double res = tot - sumNotProp; // if (res < 0) res = 0; // //Misure proporzionali // var proportionalList = splitList // .Where(m => m.SelMeasureType == MeasureTypes.PROPORTIONAL) // .ToList(); // double sumPesi = proportionalList.Sum(p => p.dDimension); // if (sumPesi == 0) sumPesi = 1; // return res / sumPesi * dDimension; //} internal JsonSplitDimension Serialize() { JsonSplitDimension JsonSplitDimension = new JsonSplitDimension(m_bIsRelative, m_dDimension, MeasureType); return JsonSplitDimension; } //internal void SetDimension(double dValue) //{ // m_dDimension = dValue; //} 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; 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; //private double m_dDimension; //private List m_MeasureTypeList = new List //{ // new IdNameStruct((int)MeasureTypes.ABSOLUTE, "Absolute"), // new IdNameStruct((int)MeasureTypes.PROPORTIONAL, "Proportional"), // new IdNameStruct((int)MeasureTypes.PERCENTAGE, "Percentage"), //}; //private MeasureTypes m_SelMeasureType; // 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; } }