unit Main; interface { TODO -cnavigatie : NavigeerNaar in interface zetten ter abstractie voor subschermen } uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, ApplicationContext, UserAgent, ProductAgent; const NAVHOME = 0; NAVLOGIN = 1; NAVZOEKPRODUCTEN = 2; type TFormMain = class(TForm) PanelMain: TPanel; procedure FormCreate(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); private FAppContext: TApplicationContext; FUserAgent: TUserAgent; FProductAgent: TProductAgent; procedure FreeControlChildrenRec(AControl: TControl); procedure ConfigureerLayoutGridPanel(GridPanel: TGridPanel); procedure PlaatsControlOpGrid(GridPanel: TGridPanel; Control: TControl; RowI: Integer; ColI: Integer; RowSpan: Integer = 1; ColSpan: Integer = 1); public procedure NavigeerNaar(schermId: Integer); end; var FormMain: TFormMain; implementation uses Subscherm, LogInScherm, ZoekProductenScherm, GebruikerScherm; {$R *.dfm} // Dit event wordt altijd aangeroepen, OnClose niet procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin FUserAgent.GebruikerAfmelden(FAppContext.UserContext); // Antwoord wordt genegeerd end; procedure TFormMain.FormCreate(Sender: TObject); begin FAppContext := TApplicationContext.Create(); FUserAgent := TUserAgent.Create(); FProductAgent := TProductAgent.Create(); { TODO -cMain: Wat doet dit in de originele applicatie?: fUiContext.ImagesScherm := TImagesScherm.Create(self); } { TODO -cMain: Kijken of "VerwerkParamStrings;" nodig is } PanelMain.Parent := Self; PanelMain.Align := TAlign.alClient; Self.NavigeerNaar(NAVLOGIN); end; procedure TFormMain.NavigeerNaar(schermId: Integer); var NieuwScherm: TControl; GridPanel: TGridPanel; NieuweGridControl: TControl; i: Integer; begin Application.ProcessMessages; // Interrupts the execution of an application so that it can process the message queue. // Volgende subscherm laden in panel // PanelMain behouden we altijd, the children can be free. for i := 0 to PanelMain.ControlCount - 1 do FreeControlChildrenRec(PanelMain.Controls[i]); case schermId of NAVHOME, NAVZOEKPRODUCTEN: begin { TODO -cUI : Onderzoeken of 'TSplitter' een beter alternatief is dan volledig een gridview } // Gebruikersgegevens scherm, zoekscherm, resultaten en detail scherm tonen. GridPanel := TGridPanel.Create(PanelMain); NieuwScherm := GridPanel; // Nieuw scherm instellen, de configuratie is grid panel specifiek (daarom andere variabele). ConfigureerLayoutGridPanel(GridPanel); // Schermen op GridPanel plaatsen // PlaatsControlOpGrid(GridPanel; Control; RowI; ColI; (opt) RowSpan; (opt)ColSpan); // Gebruikersgegevens scherm bovenaan. NieuweGridControl := TFormGebruiker.Create(GridPanel, Self, FAppContext, FAppContext.UserContext, FUserAgent); PlaatsControlOpGrid(GridPanel, NieuweGridControl, 0, 0, 1, 2); // Zoekscherm daaronder links NieuweGridControl := TFormZoekProducten.Create(GridPanel, Self, FAppContext, FProductAgent); PlaatsControlOpGrid(GridPanel, NieuweGridControl, 1, 0); // Resultaten scherm daaronder links NieuweGridControl := TFormLogin.Create(GridPanel, Self, FAppContext, FUserAgent); PlaatsControlOpGrid(GridPanel, NieuweGridControl, 2, 0); // Rechts is helemaal voor detail scherm NieuweGridControl := TFormLogin.Create(GridPanel, Self, FAppContext, FUserAgent); PlaatsControlOpGrid(GridPanel, NieuweGridControl, 1, 1, 2); end; NAVLOGIN: NieuwScherm := TFormLogin.Create(PanelMain, Self, FAppContext, FUserAgent); end; NieuwScherm.Parent := PanelMain; NieuwScherm.Align := alClient; NieuwScherm.Show; end; // Recursieve methode om de kinderen van een TWinControl te free-en (hanging pointers voorkomen) // Gebaseerd op: https://stackoverflow.com/questions/414928/is-there-any-way-to-get-all-the-controls-on-a-container-control procedure TFormMain.FreeControlChildrenRec(AControl: TControl); var item: TControl; i: Integer; begin if AControl = nil then Exit; if AControl is TWinControl then begin i := 0; // Tijden het free-en kan zijn dat er elementen verdwijnen uit de lijst. // Het aantal elementen moet dus steeds opnieuw gecontroleerd worden (een for-lus berekent dit eenmalig) while TWinControl(AControl).ControlCount < i do begin FreeControlChildrenRec(TWinControl(AControl).Controls[i]); end; end; AControl.Free(); end; procedure TFormMain.ConfigureerLayoutGridPanel(GridPanel: TGridPanel); const colLeftSize: Integer = 375; rowTopSize: Integer = 40; rowMidSize: Integer = 200; begin // Rijen en kolommen toevoegen GridPanel.RowCollection.BeginUpdate; GridPanel.ColumnCollection.BeginUpdate; GridPanel.RowCollection.Clear; GridPanel.ColumnCollection.Clear; // Balk bovenaan met vaste hoogte voor gebruikersgegevens with GridPanel.RowCollection.Add do begin SizeStyle := ssAbsolute; Value := rowTopSize; end; // Daaronder links opzoek scherm met vaste hoogte with GridPanel.RowCollection.Add do begin SizeStyle := ssAbsolute; Value := rowMidSize; end; // Daaronder het resultaten scherm, dit schaalt automatisch with GridPanel.RowCollection.Add do begin // De Autosize optie zou kijken naar het child. Hier is het de bedoeling dat het Grid Panel maximaal groeit. SizeStyle := ssPercent; Value := 100; end; // Linkerhelft van de schermen heeft vaste breedte with GridPanel.ColumnCollection.Add do begin SizeStyle := ssAbsolute; Value := colLeftSize; end; // Rechterhelft is volledig voor detail scherm with GridPanel.ColumnCollection.Add do begin // De Autosize optie zou kijken naar het child. Hier is het de bedoeling dat het Grid Panel maximaal groeit. SizeStyle := ssPercent; Value := 100; end; GridPanel.RowCollection.EndUpdate; GridPanel.ColumnCollection.EndUpdate; end; procedure TFormMain.PlaatsControlOpGrid(GridPanel: TGridPanel; Control: TControl; RowI: Integer; ColI: Integer; RowSpan: Integer = 1; ColSpan: Integer = 1); var index: Integer; begin // Toevoegen aan grid panel op eerste lege plaats (Bij het toevoegen kan dit niet worden gekozen. // Het wordt in de eerste lege plaats gezet) Control.Parent := GridPanel; Control.Visible := true; // Staat default op false Control.Align := alClient; // Maakt elementen zo groot als het kan Control.AlignWithMargins := true; // Spacing tussen de schermen // Positie binnen grid aanpassen index := GridPanel.ControlCollection.IndexOf(Control); GridPanel.ControlCollection[index].row := RowI; GridPanel.ControlCollection[index].RowSpan := RowSpan; GridPanel.ControlCollection[index].Column := ColI; GridPanel.ControlCollection[index].ColumnSpan := ColSpan; end; end.