uses Process, SysUtils, App, Dialogs, Objects, Menus, Drivers, Views, MsgBox, utils, constants; type PMbGenerateData = ^TMbGenerateData; TMbGenerateData = record path: string[128]; width: string[16]; height: string[16]; power: string[64]; zoom: string[64]; centerX: string[64]; centerY: string[64]; end; PFnGenerateData = ^TFnGenerateData; TFnGenerateData = record path: string[128]; width: string[16]; height: string[16]; fn: string[255]; zoom: string[64]; centerX: string[64]; centerY: string[64]; end; PGeneratorWindow = ^TGeneratorWindow; TGeneratorWindow = object(TDialog) pGeneratingBtn: PButton; winRect: TRect; curY: integer; procedure addField(caption: string; maxLength: integer); function addButton(caption: string; command: integer): PButton; end; PMbGeneratorWindow = ^TMbGeneratorWindow; TMbGeneratorWindow = object(TGeneratorWindow) constructor Init; end; PFnGeneratorWindow = ^TFnGeneratorWindow; TFnGeneratorWindow = object(TGeneratorWindow) constructor Init; end; TMSApp = object(TApplication) MbGeneratorWindow: PMbGeneratorWindow; FnGeneratorWindow: PFnGeneratorWindow; procedure InitStatusLine; virtual; procedure InitMenuBar; virtual; procedure HandleEvent(var Event: TEvent); virtual; procedure NewMbWindow(); procedure NewFnWindow(); procedure GenerateMultibrotSetImage(); procedure GenerateFunctionImage(); procedure ShowAbout(); procedure ShowSuccess(fname: string; t: extended); end; var MSApp: TMSApp; MbGenerateData: TMbGenerateData; FnGenerateData: TFnGenerateData; procedure TMSApp.GenerateMultibrotSetImage(); var s: AnsiString; startTime: int64; success: boolean; begin MbGeneratorWindow^.GetData(MbGenerateData); startTime := getTimestamp(); MbGeneratorWindow^.pGeneratingBtn^.show(); with MbGenerateData do begin success := RunCommand('./multibrot_imaging', [ width, height, power, zoom, centerX, centerY, path ], s); end; MbGeneratorWindow^.pGeneratingBtn^.hide(); if (success) then begin ShowSuccess(s, (getTimestamp() - startTime) / 1000); end else begin MessageBox( #3'Error'#13 + #3'Unable to execute generator!'#13, nil, mfInformation or mfOkButton ); end; end; procedure TMSApp.GenerateFunctionImage(); var s: AnsiString; startTime: int64; success: boolean; begin FnGeneratorWindow^.GetData(FnGenerateData); startTime := getTimestamp(); FnGeneratorWindow^.pGeneratingBtn^.show(); with FnGenerateData do begin success := RunCommand('./function_imaging', [ width, height, fn, zoom, centerX, centerY, path ], s); end; FnGeneratorWindow^.pGeneratingBtn^.hide(); if (success) then begin ShowSuccess(s, (getTimestamp() - startTime) / 1000); end else begin MessageBox( #3'Error'#13 + #3'Unable to execute generator!'#13, nil, mfInformation or mfOkButton ); end; end; procedure TGeneratorWindow.addField(caption: string; maxLength: integer); var il: PInputLine; r: TRect; begin caption := wrapFirstLetter(caption, '~'); r.assign(14, curY, winRect.b.x - 2, curY + 1); il := New(PInputLine, Init(r, maxLength)); Insert(il); r.assign(2, curY, 13, curY + 1); Insert(New(PLabel, Init(r, caption, il))); curY := curY + 2; end; function TGeneratorWindow.addButton(caption: string; command: integer): PButton; var r: TRect; pbtn: PButton; begin r.assign(3, curY, winRect.b.x - 1, curY + 1); pbtn := New(PButton, Init(r, caption, command, bfNormal)); Insert(pbtn); curY := curY + 2; addButton := pbtn; end; constructor TMbGeneratorWindow.Init(); var r: TRect; begin r.assign(0, 0, 60, 19); inherited Init(r, 'Multibrot generator'); Options := Options or ofCentered; HelpCtx := $F000; winRect := r; curY := 2; with MbGenerateData do begin path := './multibrot_images'; width := '512'; height := '512'; power := '2'; zoom := '1'; centerX := '0'; centerY := '0'; end; addField('Path:', 128); addField('Width:', 16); addField('Height:', 16); addField('Power:', 64); addField('Zoom:', 64); addField('Center X:', 64); addField('Center Y:', 64); addButton('Generate', cmMbGenerate); curY := curY - 2; pGeneratingBtn := addButton('Generating...', 0); pGeneratingBtn^.hide(); end; constructor TFnGeneratorWindow.Init(); var r: TRect; begin r.assign(0, 0, 60, 19); inherited Init(r, 'Function generator'); Options := Options or ofCentered; HelpCtx := $F000; winRect := r; curY := 2; with FnGenerateData do begin path := './function_images'; width := '512'; height := '512'; fn := 'sin(x*x*x * y*y) = cos(x*x * y*y*y)'; zoom := '100'; centerX := '0'; centerY := '0'; end; addField('Path:', 128); addField('Width:', 16); addField('Height:', 16); addField('Function:', 255); addField('Zoom:', 64); addField('Center X:', 64); addField('Center Y:', 64); addButton('Generate', cmFnGenerate); curY := curY - 2; pGeneratingBtn := addButton('Generating...', 0); pGeneratingBtn^.hide(); end; procedure TMSApp.NewFnWindow(); begin FnGeneratorWindow := New(PFnGeneratorWindow, Init); FnGeneratorWindow^.SetData(FnGenerateData); InsertWindow(FnGeneratorWindow); end; procedure TMSApp.NewMbWindow(); begin MbGeneratorWindow := New(PMbGeneratorWindow, Init); MbGeneratorWindow^.SetData(MbGenerateData); InsertWindow(MbGeneratorWindow); end; procedure TMSApp.ShowAbout(); begin MessageBox( #3'Math images generator'#13 + #3'Developed by Artem K.'#13 + #3'MF BMSTU 2019 - 2020', nil, mfInformation or mfOkButton ); end; procedure TMSApp.ShowSuccess(fname: string; t: extended); begin MessageBox( #3'Image was generated!'#13 + 'File name: ' + fname + #13 + 'Time spent: ' + FloatToStr(t) + ' s', nil, mfInformation or mfOkButton ); end; procedure TMSApp.HandleEvent(var Event: TEvent); begin inherited HandleEvent(Event); if Event.What = evCommand then begin case Event.Command of cmMbNew: begin NewMbWindow(); ClearEvent(Event); end; cmFnNew: begin NewFnWindow(); ClearEvent(Event); end; cmAbout: begin ShowAbout(); ClearEvent(Event); end; cmMbGenerate: begin GenerateMultibrotSetImage(); ClearEvent(Event); end; cmFnGenerate: begin GenerateFunctionImage(); ClearEvent(Event); end; end; end; end; procedure TMSApp.InitStatusLine(); var r: TRect; begin GetExtent(r); r.a.y := r.b.y - 1; New(StatusLine, Init(r, NewStatusDef(0, $EFFF, NewStatusKey('~F2~ Exit', kbF2, cmQuit, NewStatusKey('~F3~ New Mb', kbF3, cmMbNew, NewStatusKey('~F4~ New Fn', kbF4, cmFnNew, nil ))), nil) )); end; procedure TMSApp.InitMenuBar(); var r: TRect; begin GetExtent(r); r.b.y := r.a.y + 1; MenuBar := New(PMenuBar, Init(r, NewMenu( NewItem('~M~ultibrot', '', kbNoKey, cmMbNew, hcNew, NewItem('~F~unctions', '', kbNoKey, cmFnNew, hcNew, NewItem('~A~bout', '', kbNoKey, cmAbout, hcNoContext, NewItem('~E~xit', 'Alt+X', kbAltX, cmQuit, hcExit, nil)))))) ); end; begin MSApp.Init(); MSApp.Run(); MSApp.Done(); end.