1232 lines
44 KiB
C#
1232 lines
44 KiB
C#
using Egw.Window.Data;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Newtonsoft.Json;
|
|
using System.Reflection.Metadata;
|
|
using WebWindowComplex.DTO;
|
|
using WebWindowComplex.Json;
|
|
using WebWindowComplex.Models;
|
|
using static WebWindowComplex.Json.WindowConst;
|
|
|
|
namespace WebWindowComplex
|
|
{
|
|
public partial class TableComp : IDisposable
|
|
{
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// Classe override css x SVG (x rescale)
|
|
/// </summary>
|
|
[Parameter]
|
|
public string CssSvg { get; set; } = "responsive-svg";
|
|
|
|
/// <summary>
|
|
/// Preselezione valori
|
|
/// </summary>
|
|
[Parameter]
|
|
public SelectPayload? CurrSelection { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Richiesta chiusura JWD (+ refresh)
|
|
/// se torna true --> richiesta salvataggio
|
|
/// se torna false --> richiesta revert
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<bool> EC_OnClose { get; set; }
|
|
|
|
/// <summary>
|
|
/// Evento selezione template
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<TemplateSelectDTO> EC_OnSelectedTemplate { get; set; }
|
|
|
|
/// <summary>
|
|
/// Richiesta refresh SVG da JWD
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<Dictionary<string, string>> EC_OnUpdate { get; set; }
|
|
|
|
/// <summary>
|
|
/// Sollevo evento errore validazione con una lista di errori rilevati
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<Dictionary<string, string>> EC_ValidError { get; set; }
|
|
|
|
/// <summary>
|
|
/// Elenco anagrafiche di base
|
|
/// </summary>
|
|
[Parameter]
|
|
public BaseListPayload ListPayload { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// Dati live controllo (JWD, SVG, ...)
|
|
/// </summary>
|
|
[Parameter]
|
|
public LivePayload LiveData { get; set; } = null!;
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
public void Dispose()
|
|
{
|
|
if (m_CurrWindow != null)
|
|
{
|
|
m_CurrWindow.OnPreview -= M_CurrWindow_OnPreview;
|
|
m_CurrWindow = null;
|
|
}
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
/// <summary>
|
|
/// Dati live precedenti x comparazione
|
|
/// </summary>
|
|
protected LivePayload? prevLiveData = null;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Enums
|
|
|
|
protected enum CompileStep
|
|
{
|
|
Template = 0,
|
|
Tree = 1,
|
|
Frame,
|
|
Split,
|
|
Sash,
|
|
Fill,
|
|
General
|
|
}
|
|
|
|
protected enum PositionJoints
|
|
{
|
|
BL = 0, // Bottom Left
|
|
BR = 1, // Bottom Right
|
|
TR, // Top Right
|
|
TL // Top Left
|
|
}
|
|
|
|
#endregion Protected Enums
|
|
|
|
#region Protected Properties
|
|
|
|
protected List<Fill> FillList
|
|
{
|
|
get => m_FillList;
|
|
}
|
|
|
|
protected Frame FrameWindow
|
|
{
|
|
get => m_Frame!;
|
|
set => m_Frame = value;
|
|
}
|
|
|
|
protected List<ItemTable> ItemTableList
|
|
{
|
|
get => m_ItemTableList;
|
|
}
|
|
|
|
protected string m_SelSVG { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Componente SVG da mostrare
|
|
/// </summary>
|
|
protected MarkupString outSvg
|
|
{
|
|
get
|
|
{
|
|
// aggiunta gestione classe svg per posizionamento con costraints
|
|
var newSvg = LiveData.SvgPreview.Replace("<svg", $"<svg class=\"{CssSvg}\"");
|
|
return (MarkupString)newSvg;
|
|
}
|
|
}
|
|
|
|
protected List<Sash> SashList
|
|
{
|
|
get => m_SashList;
|
|
}
|
|
|
|
protected string SelColorMaterial { get; set; } = "";
|
|
protected string SelFamilyHardware { get; set; } = "";
|
|
protected string SelGlass { get; set; } = "";
|
|
|
|
protected string SelMaterial { get; set; } = ""!;
|
|
|
|
protected TemplateSelectDTO? SelTemplateDTO { get; set; } = null;
|
|
|
|
protected List<Split> SplitList
|
|
{
|
|
get => m_SplitList;
|
|
}
|
|
|
|
protected List<Splitted> SplittedList
|
|
{
|
|
get => m_SplittedList;
|
|
}
|
|
|
|
#endregion Protected Properties
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Metodo per la scelta della maniglia univoca
|
|
/// </summary>
|
|
/// <param name="sashDim"> anta su cui si seleziona la maniglia </param>
|
|
/// <returns></returns>
|
|
protected void changeHandle(SashDimension sashDim, Sash currSash)
|
|
{
|
|
// Cerco la Sash che si sta considerando nella lista Sash
|
|
foreach (Sash s in SashList)
|
|
{
|
|
if (s.Equals(currSash))
|
|
{
|
|
// Per ogni anta della Sash setto bHasHandle
|
|
foreach (SashDimension item in s.SashList)
|
|
{
|
|
if (item.Equals(sashDim))
|
|
{
|
|
item.bHasHandle = true;
|
|
}
|
|
else
|
|
{
|
|
if (item.bHasHandle)
|
|
{
|
|
switch (item.SelOpeningType)
|
|
{
|
|
case Openings.TILTTURN_LEFT:
|
|
item.SetOpeningType(Openings.TURNONLY_LEFT);
|
|
break;
|
|
|
|
case Openings.TILTTURN_RIGHT:
|
|
item.SetOpeningType(Openings.TURNONLY_RIGHT);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
item.bHasHandle = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per la scelta dello split intero nella modalità griglia
|
|
/// </summary>
|
|
/// <param name="currSplit"> split su cui si sceglie </param>
|
|
/// <returns></returns>
|
|
protected void changeStartVert(ChangeEventArgs e, Split currSplit)
|
|
{
|
|
// Cerco la Sash che si sta considerando nella lista Sash
|
|
foreach (Split s in SplitList)
|
|
{
|
|
if (s.Equals(currSplit))
|
|
{
|
|
s.SetSplitStartVert((bool)e.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per riempire la lista ItemTable in modo da poter rappresentarla come tabella
|
|
/// </summary>
|
|
/// <param name="node"> Area da classificare </param>
|
|
/// <param name="row"> numero di riga </param>
|
|
/// <param name="col"> numero di colonna </param>
|
|
/// <param name="maxRow"> numero di riga massimo </param>
|
|
/// <param name="maxCol"> numero di colonna massimo </param>
|
|
protected void CreateElementTable(Area node, int row, int col, int maxRow, int maxCol)
|
|
{
|
|
if (node != null)
|
|
{
|
|
switch (node.AreaType)
|
|
{
|
|
case AreaTypes.FRAME:
|
|
{
|
|
if (node.AreaList.Count >= 1)
|
|
ItemTableList.Add(new ItemTable(AreaTypes.FRAME, "FR", row, col, -1, node.AreaList.Count));
|
|
else
|
|
ItemTableList.Add(new ItemTable(AreaTypes.FRAME, "FR", row, col, -1, 0));
|
|
row++;
|
|
col++;
|
|
maxRow++;
|
|
maxCol++;
|
|
break;
|
|
}
|
|
case AreaTypes.SASH:
|
|
{
|
|
string nWIndow;
|
|
// Se ha fratelli
|
|
if ((node.ParentArea.ParentArea != null && node.ParentArea.ParentArea.AreaList.Count > 1) ||
|
|
(node.ParentArea != null && node.ParentArea.AreaList.Count > 1))
|
|
{
|
|
for (int i = 0; i < SashList.Count; i++)
|
|
{
|
|
if (SashList[i].Equals(node))
|
|
{
|
|
nWIndow = SashList.Count == 1 ? "" : $"{i + 1}";
|
|
// Se il nodo ha figli, salvo il numero nell'oggetto
|
|
if (node.AreaList.Count >= 1)
|
|
ItemTableList.Add(new ItemTable(AreaTypes.SASH, "WIN" + nWIndow, maxRow, col, i, node.AreaList.Count));
|
|
else
|
|
ItemTableList.Add(new ItemTable(AreaTypes.SASH, "WIN" + nWIndow, maxRow, col, i, 0));
|
|
}
|
|
}
|
|
maxCol++;
|
|
}
|
|
else
|
|
{
|
|
// Se il nodo ha figli, salvo il numero nell'oggetto
|
|
if (node.AreaList.Count >= 1)
|
|
ItemTableList.Add(new ItemTable(AreaTypes.SASH, "WIN", row, col, 0, node.AreaList.Count));
|
|
else
|
|
ItemTableList.Add(new ItemTable(AreaTypes.SASH, "WIN", row, col, 0, 0));
|
|
maxCol++;
|
|
}
|
|
row++;
|
|
col++;
|
|
maxRow++;
|
|
break;
|
|
}
|
|
case AreaTypes.FILL:
|
|
{
|
|
if ((node.ParentArea.AreaList.Count > 1 && node.ParentArea.AreaList[0].Equals(node)) ||
|
|
(node.ParentArea.ParentArea != null && node.ParentArea.ParentArea.AreaList.Count > 1 && node.ParentArea.ParentArea.AreaList[0].AreaList[0].Equals(node)))
|
|
maxCol++;
|
|
string nFill;
|
|
for (int i = 0; i < FillList.Count; i++)
|
|
{
|
|
if (FillList[i].Equals(node))
|
|
{
|
|
nFill = FillList.Count == 1 ? "" : $"{i + 1}";
|
|
ItemTableList.Add(new ItemTable(AreaTypes.FILL, "FL" + nFill, maxRow, col, i, 0));
|
|
break;
|
|
}
|
|
}
|
|
row++;
|
|
col++;
|
|
maxRow++;
|
|
break;
|
|
}
|
|
case AreaTypes.SPLIT:
|
|
{
|
|
// Se il nodo ha fratelli o cugini
|
|
if (node.ParentArea.AreaList.Count > 1 || (node.ParentArea.ParentArea != null && node.ParentArea.ParentArea.AreaList.Count > 1))
|
|
{
|
|
if (node.ParentArea.AreaList[0].Equals(node) || node.ParentArea.ParentArea.AreaList[0].Equals(node))
|
|
maxCol++;
|
|
for (int i = 0; i < SplitList.Count; i++)
|
|
{
|
|
if (SplitList[i].Equals(node))
|
|
{
|
|
string nSplit = SplitList.Count == 1 ? "" : $"{i + 1}";
|
|
if (node.AreaList.Count >= 1)
|
|
ItemTableList.Add(new ItemTable(AreaTypes.SPLIT, "SP" + nSplit, maxRow, col, i, node.AreaList.Count));
|
|
else
|
|
ItemTableList.Add(new ItemTable(AreaTypes.SPLIT, "SP" + nSplit, maxRow, col, i, 0));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < SplitList.Count; i++)
|
|
{
|
|
if (SplitList[i].Equals(node))
|
|
{
|
|
string nSplit = SplitList.Count == 1 ? "" : $"{i + 1}";
|
|
if (node.AreaList.Count >= 1)
|
|
ItemTableList.Add(new ItemTable(AreaTypes.SPLIT, "SP" + nSplit, row, col, i, node.AreaList.Count));
|
|
else
|
|
ItemTableList.Add(new ItemTable(AreaTypes.SPLIT, "SP" + nSplit, row, col, i, 0));
|
|
maxCol++;
|
|
}
|
|
}
|
|
}
|
|
row++;
|
|
col++;
|
|
maxRow++;
|
|
break;
|
|
}
|
|
case AreaTypes.SPLITTED:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
foreach (var item in node.AreaList)
|
|
{
|
|
if (maxRow < m_maxRow)
|
|
CreateElementTable(item, row, col, m_maxRow, maxCol);
|
|
else
|
|
CreateElementTable(item, row, col, maxRow, maxCol);
|
|
}
|
|
}
|
|
if (maxCol > m_maxCol)
|
|
{
|
|
m_maxCol = maxCol;
|
|
}
|
|
if (maxRow > m_maxRow)
|
|
{
|
|
m_maxRow = maxRow;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per riempire le liste Sash, Split, Splitted e Fill
|
|
/// </summary>
|
|
/// <param name="node"> Area da classificare </param>
|
|
/// <param name="IntoSash"> Parametro per sapere se si è dentro un'anta </param>
|
|
protected void CreateWindowsList(Area node, bool IntoSash)
|
|
{
|
|
if (node != null)
|
|
{
|
|
if (node.ParentArea is Sash || IntoSash == true)
|
|
IntoSash = true;
|
|
switch (node.AreaType)
|
|
{
|
|
case AreaTypes.FRAME:
|
|
{
|
|
FrameWindow = (Frame)node;
|
|
break;
|
|
}
|
|
case AreaTypes.SASH:
|
|
{
|
|
m_SashList.Add((Sash)node);
|
|
break;
|
|
}
|
|
case AreaTypes.FILL:
|
|
{
|
|
m_FillList.Add((Fill)node);
|
|
break;
|
|
}
|
|
case AreaTypes.SPLIT:
|
|
{
|
|
m_SplitList.Add((Split)node);
|
|
break;
|
|
}
|
|
case AreaTypes.SPLITTED:
|
|
{
|
|
if (node.ParentArea is Split && !IntoSash && node.AreaList[0] is Fill)
|
|
{
|
|
m_SplittedList.Add((Splitted)node);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
foreach (var item in node.AreaList)
|
|
{
|
|
CreateWindowsList(item, IntoSash);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola CSS warning
|
|
/// </summary>
|
|
/// <param name="fKey"></param>
|
|
/// <returns></returns>
|
|
protected string cssValid(string fKey)
|
|
{
|
|
return listWarnings.ContainsKey(fKey) ? "border border-danger" : "";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per determinare la descrizione del parent dello split corrente
|
|
/// </summary>
|
|
/// <param name="currSplit"> split corrente </param>
|
|
/// <returns></returns>
|
|
protected string descParentSplit(Split currSplit)
|
|
{
|
|
if ((currSplit.ParentArea is Splitted || currSplit.ParentArea is Sash) && SashList.Count > 0)
|
|
{
|
|
for (int j = 0; j < SashList.Count; j++)
|
|
{
|
|
if (SashList[j].Equals(currSplit.ParentArea))
|
|
{
|
|
return "Sash " + (j + 1);
|
|
}
|
|
else if (SashList[j].Equals(currSplit.ParentArea.ParentArea))
|
|
{
|
|
for (int k = 0; k < SashList[j].AreaList.Count; k++)
|
|
{
|
|
if (SashList[j].AreaList[k].AreaList[0].Equals(currSplit))
|
|
{
|
|
return "Sash " + (j + 1) + " - anta " + (k + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return "Frame";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Richiesta chiusura SENZA salvataggio (= restore prev)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected async Task DoClose()
|
|
{
|
|
editLock = false;
|
|
await EC_OnClose.InvokeAsync(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Anteprima SVG
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected async Task DoPreviewSvg()
|
|
{
|
|
if (m_CurrWindow != null)
|
|
{
|
|
#if DEBUG
|
|
var CurrJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize(), Formatting.Indented);
|
|
#else
|
|
var CurrJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize());
|
|
#endif
|
|
// verifico variazione JWD
|
|
if (!prevJwd.Equals(CurrJwd))
|
|
//if (!prevJwd.Equals(LiveData.CurrJwd) || !prevJwd.Equals(CurrJwd))
|
|
{
|
|
prevJwd = CurrJwd;
|
|
Dictionary<string, string> Args = new Dictionary<string, string>();
|
|
Args.Add("Mode", $"{(int)Enums.QuestionModes.PREVIEW}");
|
|
Args.Add("Jwd", CurrJwd);
|
|
await EC_OnUpdate.InvokeAsync(Args);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo di reset dei dati a quelli del template
|
|
/// </summary>
|
|
protected async Task DoReset()
|
|
{
|
|
// Aggiornati parametri di ingresso selezionati
|
|
Area.nCounterGroup = 0;
|
|
UpdateSelParameter();
|
|
JsonWindow WindowFromJson;
|
|
if (string.IsNullOrEmpty(LiveData.CurrJwd))
|
|
WindowFromJson = JsonConvert.DeserializeObject<JsonWindow>(m_SelTemplate.JWD, new PolymorphicJsonConverter()) ?? new JsonWindow("", "", "", "");
|
|
else
|
|
WindowFromJson = JsonConvert.DeserializeObject<JsonWindow>(LiveData.CurrJwd!, new PolymorphicJsonConverter()) ?? new JsonWindow("", "", "", "");
|
|
if (m_CurrWindow != null)
|
|
{
|
|
m_CurrWindow.OnPreview -= M_CurrWindow_OnPreview;
|
|
m_CurrWindow = null;
|
|
}
|
|
m_CurrWindow = WindowFromJson.Deserialize();
|
|
m_CurrWindow.OnPreview += M_CurrWindow_OnPreview;
|
|
// Aggiorante liste sash, split, splitted, fill e itemTable
|
|
UpdateLists();
|
|
currSash = -1;
|
|
currFill = -1;
|
|
currSplit = -1;
|
|
currStep = CompileStep.Tree;
|
|
editLock = false;
|
|
bError = false;
|
|
await DoPreviewSvg();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Richiesta chiusura con salvataggio
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected async Task DoSave()
|
|
{
|
|
editLock = false;
|
|
//manca salvataggio JWD
|
|
await EC_OnClose.InvokeAsync(true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Selezione del template
|
|
/// </summary>
|
|
/// <param name="newSel"> template selezionato </param>
|
|
protected async void DoSelect(TemplateSelectDTO newSel)
|
|
{
|
|
editLock = false;
|
|
SelTemplateDTO = newSel;
|
|
await EC_OnSelectedTemplate.InvokeAsync(newSel);
|
|
}
|
|
|
|
protected override void OnAfterRender(bool firstRender)
|
|
{
|
|
isLoading = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Primo init componente
|
|
/// </summary>
|
|
protected override void OnInitialized()
|
|
{
|
|
// reset editLock...
|
|
editLock = false;
|
|
// reset variabile errori
|
|
bError = false;
|
|
listErrPre = new Dictionary<string, string>();
|
|
listErrLink = new Dictionary<string, string>();
|
|
listWarnings = new Dictionary<string, string>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione update post ricezione parametri da controllo chiamante
|
|
/// </summary>
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
isLoading = true;
|
|
// SOLO SE sono presenti...
|
|
if (ListPayload.IsPopulated() && LiveData.IsValid())
|
|
{
|
|
bool updateSvg = false;
|
|
listErrPre = new Dictionary<string, string>();
|
|
listErrLink = new Dictionary<string, string>();
|
|
listWarnings = new Dictionary<string, string>();
|
|
// controllo elenchi BasePayload siano validi...
|
|
if (ListPayload.IsValid())
|
|
{
|
|
// controllo sia popolato anche per la componente LIVE
|
|
if (LiveData.IsValid())
|
|
{
|
|
// SOLO SE modificato live data...
|
|
if (prevLiveData == null || !prevLiveData.Equals(LiveData))
|
|
{
|
|
prevLiveData = new LivePayload()
|
|
{
|
|
CurrJwd = LiveData.CurrJwd,
|
|
SvgPreview = LiveData.SvgPreview
|
|
};
|
|
m_SelSVG = LiveData.SvgPreview;
|
|
// Aggiornati parametri di ingresso selezionati
|
|
UpdateSelParameter();
|
|
JsonWindow WindowFromJson = new JsonWindow("", "", "", "");
|
|
// provo a deserializzare
|
|
try
|
|
{
|
|
WindowFromJson = JsonConvert.DeserializeObject<JsonWindow>(LiveData.CurrJwd, new PolymorphicJsonConverter()) ?? new JsonWindow("", "", "", "");
|
|
setCurrWindow(WindowFromJson);
|
|
//SOLO SE non sono in edit...
|
|
if (!editLock)
|
|
{
|
|
currStep = CompileStep.Tree;
|
|
}
|
|
}
|
|
// altrimenti errore!
|
|
catch (Exception ex)
|
|
{
|
|
listErrLink.Add("Window", $"Deserializing Error:{Environment.NewLine}{ex}");
|
|
}
|
|
|
|
updateSvg = true;
|
|
}
|
|
checkWarnings();
|
|
}
|
|
else if (CurrSelection != null && CurrSelection.Template != null)
|
|
{
|
|
// Se viene passato il template selezionato oppure se non è ancora stato selezionato un template oppure se si cambia template di selezione
|
|
if (m_SelTemplate == null || (m_SelTemplate != null && CurrSelection.Template.nIndex != m_SelTemplate.nIndex) && !string.IsNullOrEmpty(CurrSelection.Template.JWD))
|
|
{
|
|
m_SelTemplate = CurrSelection.Template;
|
|
// Aggiornamento parametri di ingresso selezionati
|
|
UpdateSelParameter();
|
|
JsonWindow WindowFromJson = new JsonWindow("", "", "", "");
|
|
// provo a deserializzare
|
|
try
|
|
{
|
|
WindowFromJson = JsonConvert.DeserializeObject<JsonWindow>(m_SelTemplate.JWD, new PolymorphicJsonConverter()) ?? new JsonWindow("", "", "", "");
|
|
setCurrWindow(WindowFromJson);
|
|
currStep = CompileStep.Template;
|
|
}
|
|
// altrimenti errore!
|
|
catch (Exception ex)
|
|
{
|
|
listErrLink.Add("Window", $"Deserializing Error:{Environment.NewLine}{ex}");
|
|
}
|
|
}
|
|
updateSvg = true;
|
|
}
|
|
if (SashList.Count > 0)
|
|
{
|
|
currAnta = 0;
|
|
}
|
|
if (updateSvg)
|
|
{
|
|
await DoPreviewSvg();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
checkErrorPre();
|
|
}
|
|
isLoading = false;
|
|
}
|
|
}
|
|
|
|
protected void setCurrWindow(JsonWindow WindowFromJson)
|
|
{
|
|
if (m_CurrWindow != null)
|
|
{
|
|
m_CurrWindow.OnPreview -= M_CurrWindow_OnPreview;
|
|
m_CurrWindow = null;
|
|
}
|
|
m_CurrWindow = WindowFromJson.Deserialize();
|
|
m_CurrWindow.OnPreview += M_CurrWindow_OnPreview;
|
|
// Recupero dimensioni Frame e Joint del frame della finestra precedente
|
|
if (m_PreviousWindow != null)
|
|
{
|
|
for (int i = 0; i < 2; i++)
|
|
m_CurrWindow.AreaList[0].DimensionList[i] = m_PreviousWindow.AreaList[0].DimensionList[i];
|
|
for (int i = 0; i < 4; i++)
|
|
m_CurrWindow.AreaList[0].JointList[i] = m_PreviousWindow.AreaList[0].JointList[i];
|
|
}
|
|
if (m_CurrWindow != null)
|
|
{
|
|
// Aggiornamento liste sash, split, splitted, fill e itemTable
|
|
UpdateLists();
|
|
}
|
|
if (SashList.Count > 0)
|
|
currAnta = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo che resetta le liste (sash, split, splitted, fill e itemTable) e le crea nuovamente
|
|
/// </summary>
|
|
protected void UpdateLists()
|
|
{
|
|
m_maxCol = 0;
|
|
m_maxRow = 0;
|
|
m_FillList = new List<Fill>();
|
|
m_SashList = new List<Sash>();
|
|
m_SplitList = new List<Split>();
|
|
m_SplittedList = new List<Splitted>();
|
|
m_ItemTableList = new List<ItemTable>();
|
|
CreateWindowsList((m_CurrWindow!).AreaList[0], false);
|
|
CreateElementTable(m_CurrWindow.AreaList[0], 1, 1, 1, 1);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per settare i parmateri di ingresso selezionati
|
|
/// </summary>
|
|
protected void UpdateSelParameter()
|
|
{
|
|
Sash.m_HardwareCompleteList = ListPayload.Hardware;
|
|
Sash.s_FamilyHardwareList = ListPayload.FamilyHardware;
|
|
if (CurrSelection != null && CurrSelection.IsValid())
|
|
{
|
|
SelFamilyHardware = CurrSelection.FamilyHardware ?? "";
|
|
SelColorMaterial = CurrSelection.ColorMaterial ?? "";
|
|
SelMaterial = CurrSelection.Material ?? "";
|
|
SelGlass = CurrSelection.Glass ?? "";
|
|
}
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Private Fields
|
|
|
|
private bool bError = false;
|
|
|
|
private int currAnta = 0;
|
|
|
|
private int currFill = -1;
|
|
|
|
private int currSash = -1;
|
|
|
|
private int currSplit = -1;
|
|
|
|
private CompileStep currStep;
|
|
|
|
private bool editLock = false;
|
|
|
|
/// <summary>
|
|
/// Booleana fase loading
|
|
/// </summary>
|
|
private bool isLoading = false;
|
|
|
|
/// <summary>
|
|
/// ELenco errori di coerenza/link dati (vanno risolti per disegnare/procedere)
|
|
/// </summary>
|
|
private Dictionary<string, string> listErrLink = new Dictionary<string, string>();
|
|
|
|
/// <summary>
|
|
/// Elenco errori preliminari (mancano elementi di base di validazione modello dati))
|
|
/// </summary>
|
|
private Dictionary<string, string> listErrPre = new Dictionary<string, string>();
|
|
|
|
/// <summary>
|
|
/// Elenco warnings non bloccanti
|
|
/// </summary>
|
|
private Dictionary<string, string> listWarnings = new Dictionary<string, string>();
|
|
|
|
private List<Fill> m_FillList = new List<Fill>();
|
|
|
|
private Frame? m_Frame;
|
|
|
|
private List<ItemTable> m_ItemTableList = new List<ItemTable>();
|
|
|
|
private int m_maxCol = 0;
|
|
|
|
private int m_maxRow = 0;
|
|
|
|
private List<Sash> m_SashList = new List<Sash>();
|
|
|
|
private List<Split> m_SplitList = new List<Split>();
|
|
|
|
private List<Splitted> m_SplittedList = new List<Splitted>();
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Properties
|
|
|
|
private Window? m_CurrWindow { get; set; } = null;
|
|
|
|
private Window? m_PreviousWindow { get; set; } = null;
|
|
|
|
private string m_SelFamilyHardware { get; set; } = "";
|
|
|
|
private Template m_SelTemplate { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// Salvataggio JWD precedente x evitare loop su update
|
|
/// </summary>
|
|
private string prevJwd { get; set; } = "";
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Private Methods
|
|
|
|
private void AddSashToFrame(Frame f)
|
|
{
|
|
bError = f.AddFirstSash();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per andare allo step successivo
|
|
/// </summary>
|
|
/// <param name="newStep"> step successivo </param>
|
|
private void AdvStep(CompileStep newStep)
|
|
{
|
|
currStep = newStep;
|
|
currSash = -1;
|
|
currFill = -1;
|
|
currSplit = -1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola larghezza colonna button nav
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private string buttonCss()
|
|
{
|
|
return (currStep == CompileStep.Template) ? "col-4 d-grid gap-1 d-md-flex justify-content-md-end align-items-center" : "col-4 d-grid gap-1 d-md-flex justify-content-md-end align-items-center";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola bottone selezionato per il Fill
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private string buttonFillCss(FillTypes currFillTypes)
|
|
{
|
|
if (FillList.ElementAt(currFill).SelFillType == currFillTypes)
|
|
return "btn btn-secondary btn-sm";
|
|
else
|
|
return "btn btn-outline-secondary btn-sm";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per settare tutti i Fill in contemporanea
|
|
/// </summary>
|
|
/// <param name="type"> tipo di riempimento (GLASS o WOOD) </param>
|
|
/// <returns></returns>
|
|
private async Task ChangeAllFill(FillTypes type)
|
|
{
|
|
foreach (Fill currFill in FillList)
|
|
{
|
|
currFill.SetFillType(type);
|
|
}
|
|
await DoPreviewSvg();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per settare tutti i Joints di Frame o Sash come ANGLED o FULL_H o FULL_V
|
|
/// </summary>
|
|
/// <param name="n_type"> tipo di giunzione (ANGLED o FULL_H o FULL_V) </param>
|
|
/// <param name="area"> area su cui eseguire la funzione (Frame o Sash) </param>
|
|
/// <returns></returns>
|
|
private async Task ChangeAllJoints(WindowConst.Joints type, Area area)
|
|
{
|
|
if (area is Frame)
|
|
{
|
|
foreach (Joint joint in FrameWindow.JointList)
|
|
{
|
|
joint.SetSelJointType(type);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Sash a = (Sash)area;
|
|
foreach (Joint joint in a.JointList)
|
|
{
|
|
joint.SetSelJointType(type);
|
|
}
|
|
}
|
|
await DoPreviewSvg();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per settare tutti i Fill in contemporanea
|
|
/// </summary>
|
|
/// <param name="type"> tipo di riempimento (GLASS o WOOD) </param>
|
|
/// <returns></returns>
|
|
private async Task ChangeOneFill(FillTypes type)
|
|
{
|
|
Fill fillChange = FillList.ElementAt(currFill);
|
|
fillChange.SetFillType(type);
|
|
await DoPreviewSvg();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica errori prelimionari per mostrare dove sia il problema
|
|
/// </summary>
|
|
private void checkErrorPre()
|
|
{
|
|
// verifico 1:1 le liste e indico cosa manca
|
|
if (ListPayload.Hardware == null || ListPayload.Hardware.Count == 0)
|
|
{
|
|
listErrPre.Add("Hardware", "Missing Hardware List!");
|
|
}
|
|
else
|
|
{
|
|
if (ListPayload.FamilyHardware == null || ListPayload.FamilyHardware.Count == 0)
|
|
{
|
|
listErrPre.Add("FamilyHardware", "Missing Family HW List!");
|
|
}
|
|
}
|
|
if (ListPayload.Glass == null || ListPayload.Glass.Count == 0)
|
|
{
|
|
listErrPre.Add("Glass", "Missing Glass List!");
|
|
}
|
|
if (ListPayload.Material == null || ListPayload.Material.Count == 0)
|
|
{
|
|
listErrPre.Add("Material", "Missing Material List!");
|
|
}
|
|
if (ListPayload.ColorMaterial == null || ListPayload.ColorMaterial.Count == 0)
|
|
{
|
|
listErrPre.Add("ColorMaterial", "Missing ColorMaterial List!");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica warning minori (es coerenza colori...)
|
|
/// </summary>
|
|
private void checkWarnings()
|
|
{
|
|
// verifico 1:1 le liste e i valori siano coerenti...
|
|
if (ListPayload.ColorMaterial != null && ListPayload.ColorMaterial.Count > 0)
|
|
{
|
|
// verifico colore attuale sia consistente...
|
|
if (m_CurrWindow != null)
|
|
{
|
|
if (!ListPayload.ColorMaterial.Contains(m_CurrWindow.sColorMaterial))
|
|
{
|
|
listWarnings.Add("ColorMaterial", $"Missing Color: {m_CurrWindow.sColorMaterial}");
|
|
}
|
|
if (!ListPayload.Glass.Contains(m_CurrWindow.sGlass))
|
|
{
|
|
listWarnings.Add("Glass", $"Missing Glass: {m_CurrWindow.sGlass}");
|
|
}
|
|
if (!ListPayload.Material.Contains(m_CurrWindow.sMaterial))
|
|
{
|
|
listWarnings.Add("Material", $"Missing Material: {m_CurrWindow.sMaterial}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per copiare contenuto di un'anta in un'altra anta
|
|
/// </summary>
|
|
/// <param name="sashItem"> Sash corrispondente all'anta </param>
|
|
/// <param name="IndexCopy"> Indice dell'anta che si copia </param>
|
|
/// <param name="IndexModify"> Indice dell'anta che si modifica </param>
|
|
private async Task CopyContentSash(Sash sashItem, int IndexCopy, int IndexModify)
|
|
{
|
|
// Anta selezionata
|
|
Area sashSplitted = sashItem.AreaList[IndexModify];
|
|
// Rimuovo riempimento da anta selezionata
|
|
sashSplitted.AreaList.RemoveAt(0);
|
|
// Creo la copia dell'anta scelta
|
|
Area a = sashItem.AreaList[IndexCopy].AreaList[0].Copy(sashSplitted);
|
|
// Aggiungo copia all'anta selezionata
|
|
sashItem.AreaList[IndexModify].AreaList.Add(a);
|
|
await DoPreviewSvg();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per copiare una Sash intera
|
|
/// </summary>
|
|
/// <param name="currSplitted"> Area Splitted corrente </param>
|
|
/// <param name="numSash"> Indice della Sash che si vuole copiare </param>
|
|
/// <returns></returns>
|
|
private async Task CopySash(Splitted currSplitted, int numSash)
|
|
{
|
|
//Rimuovo contenuto di Splitted e rimuovo area da conteggio gruppi
|
|
currSplitted.AreaList.RemoveAll(i => i != null);
|
|
//Area.DelCounterGroup();
|
|
// Copio sash
|
|
Area a = SashList[numSash].Copy(currSplitted);
|
|
a.SetParentArea(currSplitted);
|
|
// Aggiungo copia a Splitted
|
|
currSplitted.AreaList.Add(a);
|
|
await DoPreviewSvg();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per riempire tabella con contenuto vuoto o con i simboli per rappresentare la struttura
|
|
/// </summary>
|
|
/// <param name="row"> riga della cella </param>
|
|
/// <param name="col"> colonna della cella </param>
|
|
/// <returns></returns>
|
|
private string FillTable(int row, int col)
|
|
{
|
|
List<ItemTable> itemSameCol = new List<ItemTable>();
|
|
for (int k = 0; k < row; k++)
|
|
{
|
|
if (ItemTableList[k].Col == col + 1)
|
|
{
|
|
itemSameCol.Add(ItemTableList[k]);
|
|
}
|
|
continue;
|
|
}
|
|
int numItemNextCol = 0;
|
|
for (int k = 0; k < row; k++)
|
|
{
|
|
if (ItemTableList[k].Row <= row && ItemTableList[k].Col == col + 2)
|
|
{
|
|
numItemNextCol++;
|
|
}
|
|
continue;
|
|
}
|
|
if (itemSameCol.Count > 1)
|
|
{
|
|
for (int i = 0; i <= itemSameCol.Count - 2; i++)
|
|
{
|
|
if (itemSameCol[i].NumChild > 0)
|
|
numItemNextCol = numItemNextCol - itemSameCol[i].NumChild;
|
|
}
|
|
}
|
|
if (itemSameCol.Count > 0)
|
|
{
|
|
// Sono alla riga successiva di un elemento e nella stessa colonna
|
|
if (itemSameCol.Last().Row == row)
|
|
{
|
|
// se ha un solo figlio
|
|
if (itemSameCol.Last().NumChild == 1)
|
|
{
|
|
return "└";
|
|
}
|
|
else if (itemSameCol.Last().NumChild == 0)
|
|
{
|
|
return " ";
|
|
}
|
|
else
|
|
{
|
|
return "├";
|
|
}
|
|
}
|
|
// Non sono alla riga successiva
|
|
else
|
|
{
|
|
// se ha un solo figlio
|
|
if (itemSameCol.Last().NumChild == 1)
|
|
{
|
|
return " ";
|
|
}
|
|
else if (col + 2 <= m_maxCol && ItemTableList[row].Col == col + 2)
|
|
{
|
|
if (numItemNextCol < itemSameCol.Last().NumChild && numItemNextCol != (itemSameCol.Last().NumChild - 1))
|
|
{
|
|
return "├";
|
|
}
|
|
return "└";
|
|
}
|
|
else if (numItemNextCol < itemSameCol.Last().NumChild)
|
|
{
|
|
return "│";
|
|
}
|
|
else
|
|
{
|
|
return " ";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return " ";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola larghezza colonna header nav
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private string headerCss()
|
|
{
|
|
return (currStep == CompileStep.Template) ? "col-8 d-grid px-2 d-md-flex justify-content-md-start" : "col-8 d-grid px-2 d-md-flex justify-content-md-start";
|
|
}
|
|
|
|
private void M_CurrWindow_OnPreview(object? sender, OnPreviewEventArgs e)
|
|
{
|
|
Dictionary<string, string> Args = new Dictionary<string, string>();
|
|
Args.Add("Mode", $"{(int)Enums.QuestionModes.PREVIEW}");
|
|
Args.Add("Jwd", e.sJwd);
|
|
EC_OnUpdate.InvokeAsync(Args);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola larghezza colonna contenente nav da mostrare
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private string mainCss()
|
|
{
|
|
return (currStep == CompileStep.Template) ? "col-12" : "col-6";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per cambiare step e aggiornare preview svg
|
|
/// </summary>
|
|
/// <param name="newStep"> step successivo </param>
|
|
private void NextStepAndPreview(CompileStep newStep, int Index = -1)
|
|
{
|
|
editLock = true;
|
|
currStep = newStep;
|
|
switch (newStep)
|
|
{
|
|
case CompileStep.Sash:
|
|
{
|
|
currSash = Index;
|
|
currFill = -1;
|
|
currSplit = -1;
|
|
break;
|
|
}
|
|
case CompileStep.Fill:
|
|
{
|
|
currFill = Index;
|
|
currSash = -1;
|
|
currSplit = -1;
|
|
break;
|
|
}
|
|
case CompileStep.Split:
|
|
{
|
|
currSplit = Index;
|
|
currSash = -1;
|
|
currFill = -1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if false
|
|
await DoPreviewSvg();
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per eliminare Split o Sash
|
|
/// </summary>
|
|
/// <param name="currArea"> Area corrente </param>
|
|
/// <returns></returns>
|
|
private void RemoveArea(Area currArea)
|
|
{
|
|
if (currArea is Split)
|
|
((Split)currArea).Remove();
|
|
else if (currArea is Sash)
|
|
{
|
|
((Sash)currArea).Remove();
|
|
}
|
|
currStep = CompileStep.Tree;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ritorno step Tree
|
|
/// </summary>
|
|
/// <param name="args"></param>
|
|
private void ReturnTree(bool args)
|
|
{
|
|
AdvStep(CompileStep.Tree);
|
|
}
|
|
|
|
private void SelectColor(string newVal)
|
|
{
|
|
if (m_CurrWindow != null)
|
|
{
|
|
m_CurrWindow.sColorMaterial = newVal;
|
|
}
|
|
}
|
|
|
|
private void SelectGlass(string newVal)
|
|
{
|
|
if (m_CurrWindow != null)
|
|
{
|
|
m_CurrWindow.sGlass = newVal;
|
|
}
|
|
}
|
|
|
|
private void SelectMat(string newVal)
|
|
{
|
|
if (m_CurrWindow != null)
|
|
{
|
|
m_CurrWindow.sMaterial = newVal;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo per scambiare due aree di uno split
|
|
/// </summary>
|
|
/// <param name="currArea"> Area corrente </param>
|
|
/// <returns></returns>
|
|
private async Task SwapTwoAree(Area currArea)
|
|
{
|
|
currArea.SwapAree();
|
|
await DoPreviewSvg();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola il css del tab selezionato
|
|
/// </summary>
|
|
/// <param name="testStep"> Step </param>
|
|
/// <returns></returns>
|
|
private string tabNavCss(CompileStep testStep, int Index = -1)
|
|
{
|
|
if (testStep == CompileStep.Sash)
|
|
{
|
|
if ((currSash == 0 && Index == 0) || (currSash == 1 && Index == 1))
|
|
return "nav-link active fw-bold";
|
|
else
|
|
return "nav-link text-secondary";
|
|
}
|
|
else if (testStep == CompileStep.Fill)
|
|
{
|
|
if ((currFill == 0 && Index == 0) || (currFill == 1 && Index == 1))
|
|
return "nav-link active fw-bold";
|
|
else
|
|
return "nav-link text-secondary";
|
|
}
|
|
else if (testStep == CompileStep.Split)
|
|
{
|
|
if ((currSplit == 0 && Index == 0) || (currSplit == 1 && Index == 1))
|
|
return "nav-link active fw-bold";
|
|
else
|
|
return "nav-link text-secondary";
|
|
}
|
|
return (testStep == currStep) ? "nav-link active fw-bold" : "nav-link text-secondary";
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |