Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit View;
- interface
- uses
- Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
- Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls, System.Actions,
- Vcl.ActnList, Model, Vcl.Menus, Vcl.ExtCtrls, Math;
- type
- TMainForm = class(TForm)
- gbList: TGroupBox;
- btnFindFlow: TButton;
- sgAdjacencyList: TStringGrid;
- ActionList: TActionList;
- edListSize: TEdit;
- MainMenu: TMainMenu;
- Open: TMenuItem;
- N1: TMenuItem;
- Exit: TMenuItem;
- Exit1: TMenuItem;
- Help: TMenuItem;
- actionSaveToFile: TAction;
- OpenDialog: TOpenDialog;
- PopupMenu: TPopupMenu;
- Areyouserious1: TMenuItem;
- lbAmountNodes: TLabel;
- actionHelpClick: TAction;
- actionClickTransformFromList: TAction;
- lbInformation: TLabel;
- lbMaxFlow: TLabel;
- imgDrawPlace: TImage;
- sgEdgesCost: TStringGrid;
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- procedure edListSizeKeyPress(Sender: TObject; var Key: Char);
- procedure edListSizeChange(Sender: TObject);
- procedure sgAdjacencyListKeyPress(Sender: TObject; var Key: Char);
- procedure FormCreate(Sender: TObject);
- procedure sgAdjacencyListKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure actionSaveToFileExecute(Sender: TObject);
- procedure Exit1Click(Sender: TObject);
- procedure actionHelpClickExecute(Sender: TObject);
- procedure actionClickTransformFromListExecute(Sender: TObject);
- procedure actionClickTranformExecute(Sender: TObject);
- private
- const
- NodeRadius = 20;
- EdgesLen = 100;
- PenWidth = 2;
- PenArrowWidth = 7;
- CentrePoint: TPoint = (X: 200; Y: 200);
- procedure ClearDrawPlace;
- procedure RedrawFixedColInAdjancyList(const sg: TStringGrid);
- procedure DrawCircle(const Value, Radius: Integer; const Pos: TPoint);
- procedure DrawLine(const FPoint, SPoint: TPoint);
- procedure DrawArrow(FPoint, SPoint: TPoint; const Color: TColor);
- procedure DrawGraph(const StartAdjacentMatrix, FinalAdjacentMatrix :TMatrix);
- function IsCorrectKey(const Key: char; const Text: string): Boolean;
- function CountSecontPointPosByAngle(const Angle, Linelen: integer;
- const FPoint: TPoint): TPoint;
- procedure Clear(const sg: TStrinGgrid);
- procedure ClearFlowlabel;
- //Надо изменить
- procedure WriteInformationToFile(var f: TextFile;
- const sgAdjacencyList, sgAdjacencyMatrix: TStringGrid);
- public
- procedure ShowErrorMsg(const Msg, MsgHead: string);
- end;
- const
- msgFileError = 'Critical error writing to file';
- headFileError = 'Error';
- var
- MainForm: TMainForm;
- implementation
- {$R *.dfm}
- procedure TMainForm.ShowErrorMsg(const Msg, MsgHead: string);
- begin
- MessageBox(Handle, PChar(Msg), PChar(MsgHead), MB_ICONERROR)
- end;
- procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
- const
- Question = 'Are you sure?';
- begin
- if MessageBox(Handle, PChar(Question), PChar(Question), MB_ICONINFORMATION + MB_YESNO) = mrno then
- Action := caNone;
- end;
- procedure TMainForm.FormCreate(Sender: TObject);
- begin
- RedrawFixedColInAdjancyList(sgAdjacencyList);
- RedrawFixedColInAdjancyList(sgEdgesCost);
- end;
- procedure TMainForm.edListSizeChange(Sender: TObject);
- const
- FixedCol = 1;
- var
- RowCount: integer;
- begin
- ClearFlowlabel;
- if (Sender as TEdit).Text <> '' then
- begin
- RowCount := StrToInt((Sender as TEdit).Text);
- sgAdjacencyList.RowCount := RowCount;
- sgAdjacencyList.ColCount := RowCount + FixedCol;
- sgEdgesCost.RowCount := RowCount;
- sgEdgesCost.ColCount := RowCount + FixedCol;
- end;
- ClearDrawPlace;
- Clear(sgAdjacencyList);
- Clear(sgEdgesCost);
- RedrawFixedColInAdjancyList(sgAdjacencyList);
- RedrawFixedColInAdjancyList(sgEdgesCost);
- end;
- procedure TMainForm.RedrawFixedColInAdjancyList(const sg: TStringGrid);
- var
- i: integer;
- begin
- if sg.FixedCols <> 0 then
- for i := 0 to (sg.RowCount - 1) do
- sg.Cells[0, i] := IntToStr(i+1) + ' -> ';
- end;
- procedure TMainForm.sgAdjacencyListKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- begin
- if Key = VK_INSERT then
- Key := 0;
- end;
- procedure TMainForm.ClearFlowlabel;
- begin
- lbMaxFlow.Caption := '';
- end;
- procedure TMainForm.sgAdjacencyListKeyPress(Sender: TObject; var Key: Char);
- const
- BackSpace = #8;
- var
- CurCellText, PreviousCellText: string;
- CurI, CurJ, j: integer;
- begin
- ClearDrawPlace;
- ClearFlowLabel;
- CurI := (Sender as TStringGrid).Row;
- CurJ := (Sender as TStringGrid).Col;
- CurCellText := (Sender as TStringGrid).Cells[CurJ, CurI];
- PreviousCellText := (Sender as TStringGrid).Cells[CurJ - 1, CurI];
- if (not IsCorrectKey(Key, CurCellText) or (PreviousCellText = '')) then
- Key := #0;
- if Key = BackSpace then
- for j := CurJ to (Sender as TStringGrid).ColCount - 1 do
- (Sender as TStringGrid).Cells[j, CurI] := '';
- end;
- procedure TMainForm.ClearDrawPlace;
- const
- StandartColor = clWhite;
- var
- OldColor: TColor;
- begin
- OldColor := imgDrawPlace.Canvas.Brush.Color;
- imgDrawPlace.Canvas.Brush.Color := StandartColor;
- imgDrawPlace.Canvas.FillRect(Rect(0, 0, imgDrawPlace.Width, imgDrawPlace.Height));
- imgDrawPlace.Canvas.Brush.Color := OldColor;
- end;
- function IsCorrectKeyInedListSize(const Key: char; const Text: string): Boolean;
- const
- BackSpace = #8;
- ValidSize = ['2'..'6', #8];
- begin
- if (Length(Text) <> 0) and (Key <> BackSpace) then
- Result := False
- else
- Result := Key in ValidSize;
- end;
- procedure TMainForm.edListSizeKeyPress(Sender: TObject; var Key: Char);
- begin
- if (not IsCorrectKeyInedListSize(Key, (Sender as TEdit).Text)) then
- Key := #0;
- end;
- procedure TMainForm.Exit1Click(Sender: TObject);
- begin
- Close;
- end;
- procedure TMainForm.actionClickTransformFromListExecute(Sender: TObject);
- var
- ListArr: TListArr;
- StartAdjacencyMatrix, FinalAdjacencyMatrix: TMatrix;
- FlowSize: Integer;
- begin
- ListArr := InitList(sgAdjacencyList);
- if Length(ListArr) <> 0 then
- begin
- StartAdjacencyMatrix := CreateAdjacencyMatrixFromList(ListArr);
- // FinalAdjacencyMatrix := FindFinalAnjacentMatrix(StartAdjacencyMatrix, FlowSize);
- lbMaxFlow.Caption := IntToStr(FlowSize);
- DrawGraph(StartAdjacencyMatrix, FinalAdjacencyMatrix);
- end;
- end;
- procedure TMainForm.actionClickTranformExecute(Sender: TObject);
- const
- msgIncorrectList = 'Incorrect list, please, read help and try again.';
- var
- StartAdjacencyMatrix, FinalAdjacencyMatrix: TMatrix;
- FlowSize: Integer;
- i: Integer;
- j: Integer;
- IsCorrectLists: Boolean;
- begin
- IsCorrectLists := True;
- TransformToMatrix(StartAdjacencyMatrix, sgAdjacencyList);
- TransformToMatrix(FinalAdjacencyMatrix, sgEdgesCost);
- if IsCorrectList(StartAdjacencyMatrix) then
- begin
- for i := 0 to High(StartAdjacencyMatrix) do
- begin
- for j := 0 to High(StartAdjacencyMatrix) do
- if StartAdjacencyMatrix[i, j] <> 0 then
- if FinalAdjacencyMatrix[i, j] = 0 then
- begin
- IsCorrectLists := False;
- ShowMessage(msgIncorrectList);
- Break;
- end;
- if not IsCorrectLists then
- Break;
- end;
- if IsCorrectLists then
- begin
- StartAdjacencyMatrix := CreateAdjacencyMatrix(StartAdjacencyMatrix, FinalAdjacencyMatrix);
- FinalAdjacencyMatrix := FindFinalAnjacentMatrix(StartAdjacencyMatrix, FlowSize);
- lbMaxFlow.Caption := IntToStr(FlowSize);
- DrawGraph(StartAdjacencyMatrix, FinalAdjacencyMatrix);
- end;
- end
- else
- ShowMessage(msgIncorrectList);
- end;
- procedure TMainForm.actionHelpClickExecute(Sender: TObject);
- const
- msgAboutProgram1 = 'This program tranform adjancy lists in the adjacency matrix.';
- msgAboutProgram2 = 'For translation is necessary to fill lists in the increasing order, ';
- msgAboutProgram3 = 'the biggest number you may use it is amount nodes in the your graph.';
- msgHead = 'Help';
- begin
- MessageBox(Handle, PChar(msgAboutProgram1 + #13 + msgAboutProgram2 + #13 + msgAboutProgram3),
- PChar(msgHead), MB_ICONINFORMATION);
- end;
- procedure TMainForm.actionSaveToFileExecute(Sender: TObject);
- var
- FileName: string;
- f: TextFile;
- begin
- if OpenDialog.Execute then
- begin
- FileName := OpenDialog.FileName;
- if FileExists(FileName) then
- begin
- try
- AssignFile(f, FileName);
- Rewrite(f);
- except
- MessageBox(Handle, PChar(msgFileError), PChar(headFileError), MB_ICONERROR);
- end;
- end;
- CloseFile(f);
- end;
- end;
- procedure TMainForm.WriteInformationToFile(var f: TextFile;
- const sgAdjacencyList, sgAdjacencyMatrix: TStringGrid);
- const
- msgList = 'List: ';
- msgMatrix = 'Matrix: ';
- var
- i,j: integer;
- begin
- Writeln(f, msgList);
- for i := 0 to (sgAdjacencyList.RowCount - 1) do
- begin
- Write(f, IntToStr(i) + ': ');
- for j := 1 to (sgAdjacencyList.ColCount - 1) do
- if sgAdjacencyList.Cells[j, i] <> '' then
- Write(f, sgAdjacencyList.Cells[j, i] + ' -> ');
- Writeln(f);
- end;
- Writeln(f);
- Writeln(f, msgMatrix);
- for i := 1 to (sgAdjacencyMatrix.RowCount - 1) do
- begin
- for j := 1 to (sgAdjacencyMatrix.ColCount - 1) do
- Write(f, sgAdjacencyMatrix.Cells[j, i] + ' ');
- Writeln(f);
- end;
- end;
- procedure TMainForm.Clear(const sg: TStrinGgrid);
- var
- i, j: Integer;
- begin
- for i := (0 + sg.FixedRows) to sg.RowCount do
- for j := (0 + sg.FixedCols) to sg.ColCount do
- sg.Cells[j, i] := '';
- end;
- function TMainForm.IsCorrectKey(const Key: char; const Text: string): Boolean;
- const
- BackSpace = #8;
- ValidSize = ['1'..'9', #8];
- begin
- if (Length(Text) > 2) and (Key <> BackSpace) then
- Result := False
- else
- Result := Key in ValidSize;
- end;
- procedure TMainForm.DrawCircle(const Value, Radius: Integer; const Pos: TPoint);
- const
- Offset = 5;
- TextSize = 13;
- var
- XTextOffset, YTextOffset: integer;
- begin
- XTextOffset := (Radius div Offset);
- YTextOffset := (Radius div Offset) + Offset;
- imgDrawPlace.Canvas.Pen.Width := PenWidth;
- imgDrawPlace.Canvas.Ellipse((Pos.X - Radius), (Pos.Y - Radius),
- (Pos.X + Radius), (Pos.Y + Radius));
- imgDrawPlace.Canvas.Font.Size := TextSize;
- imgDrawPlace.Canvas.TextOut(Pos.X - XTextOffset, Pos.Y - YTextOffset, IntToStr(Value));
- end;
- procedure TMainForm.DrawLine(const FPoint, SPoint: TPoint);
- begin
- imgDrawPlace.Canvas.MoveTo(FPoint.X, FPoint.Y);
- imgDrawPlace.Canvas.LineTo(SPoint.X, SPoint.Y);
- end;
- procedure TMainForm.DrawArrow(FPoint, SPoint: TPoint; const Color: TColor);
- const
- ArrowLenCoefficient = 4;
- var
- OldPenColor: TColor;
- OldPenWidth: Integer;
- XOffset, YOffset: Integer;
- begin
- OldPenColor := imgDrawPlace.Canvas.Pen.Color;
- imgDrawPlace.Canvas.Pen.Color := Color;
- DrawLine(FPoint, SPoint);
- OldPenWidth := imgDrawPlace.Canvas.Pen.Width;
- imgDrawPlace.Canvas.Pen.Width := PenArrowWidth;
- XOffset := Abs(FPoint.X - SPoint.X) div ArrowLenCoefficient;
- YOffset := Abs(FPoint.Y - SPoint.Y) div ArrowLenCoefficient;
- if Max(FPoint.X, SPoint.X) = SPoint.X then
- FPoint.X := SPoint.X - XOffset
- else
- FPoint.X := SPoint.X + XOffset;
- if Max(FPoint.Y, SPoint.Y) = SPoint.Y then
- FPoint.Y := SPoint.Y - YOffset
- else
- FPoint.Y := SPoint.Y + YOffset;
- DrawLine(FPoint, SPoint);
- imgDrawPlace.Canvas.Pen.Width := OldPenWidth;
- imgDrawPlace.Canvas.Pen.Color := OldPenColor;
- end;
- procedure TMainForm.DrawGraph(const StartAdjacentMatrix, FinalAdjacentMatrix: TMatrix);
- const
- StandartColor = clBlack;
- HilighedColor = clMoneyGreen;
- var
- CurAngle, AngleOffset, i, j, StartAdjacentMatrixLen: Integer;
- NodesPositions: array of TPoint;
- begin
- StartAdjacentMatrixLen := Length(StartAdjacentMatrix);
- AngleOffset := (360 div StartAdjacentMatrixLen);
- SetLength(NodesPositions, StartAdjacentMatrixLen);
- CurAngle := 0;
- for i := 0 to High(StartAdjacentMatrix) do
- begin
- NodesPositions[i] := CountSecontPointPosByAngle(CurAngle, EdgesLen, CentrePoint);
- Inc(CurAngle, AngleOffset);
- end;
- //Draw arrows by standart color
- for i := 0 to High(StartAdjacentMatrix) do
- for j := 0 to High(StartAdjacentMatrix) do
- if StartAdjacentMatrix[i, j] <> 0 then
- DrawArrow(NodesPositions[i], NodesPositions[j], StandartColor);
- //Draw useful arrow special color (above)
- for i := 0 to High(StartAdjacentMatrix) do
- for j := i to High(StartAdjacentMatrix) do
- if StartAdjacentMatrix[i, j] <> FinalAdjacentMatrix[i, j] then
- DrawArrow(NodesPositions[i], NodesPositions[j], HilighedColor);
- for i := 0 to High(NodesPositions) do
- DrawCircle(i + 1, NodeRadius, NodesPositions[i]);
- end;
- function TMainForm.CountSecontPointPosByAngle(const Angle, Linelen: integer;
- const FPoint: TPoint): TPoint;
- begin
- Result.X := FPoint.X + Round(Linelen * Cos(Angle * Pi / 180));
- Result.Y := FPoint.Y - Round(Linelen * Sin(Angle * Pi / 180));
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement