По мотивам - MindStream в движении. Развиваем "предметную область". Только код
Оказалось, что TmsDiagrammsController - ПАДАЕТ в результате предыдущих коммитов.
ПОЧЕМУ?
Объяснять - НЕ БУДУ.
Намекну - "из-за ImsDiagrammsHolder".
"используем ImsDiagrammsController, а НЕ TmsDiagrammsController. Embarcadero нас к этому ТОЛКАЕТ."
https://bitbucket.org/ingword/mindstream/src/fd5306a0575a10f8a8bf10bedeca955af9788caa/msInterfaces.pas?at=MS-7_Lulin_Upgrade
Только код.
А вообще на Borland и Embarcadero - "у меня давно зуб".
Оказалось, что TmsDiagrammsController - ПАДАЕТ в результате предыдущих коммитов.
ПОЧЕМУ?
Объяснять - НЕ БУДУ.
Намекну - "из-за ImsDiagrammsHolder".
"используем ImsDiagrammsController, а НЕ TmsDiagrammsController. Embarcadero нас к этому ТОЛКАЕТ."
https://bitbucket.org/ingword/mindstream/src/fd5306a0575a10f8a8bf10bedeca955af9788caa/msInterfaces.pas?at=MS-7_Lulin_Upgrade
Только код.
unit msInterfaces; interface uses System.Types, System.Classes, FMX.Graphics, System.UITypes, msSerializeInterfaces, Generics.Collections ; type ImsShape = interface; ImsShapeByPt = interface function ShapeByPt(const aPoint: TPointF): ImsShape; end;//ImsShapeByPt ImsShapesController = interface(ImsShapeByPt) procedure RemoveShape(const aShape: ImsShape); end;//ImsShapesController // - тут бы иметь МНОЖЕСТВЕННОЕ наследование интерфейсов, но Delphi его не поддерживает // А вот с UML - мы его ПОТОМ СГЕНЕРИРУЕМ TmsDrawContext = record // Контекст рисования. // "Лирика" - тут - http://habrahabr.ru/post/170125/ // Ну и "связанное" - https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D1%80%D0%B0%D1%82%D0%B5%D0%B3%D0%B8%D1%8F_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F) // // Зачем же НАМ нужен "контекст"? // // Всё - БАНАЛЬНО. Чтобы НЕ ТРОГАТЬ сигнатуры методов. Мысль понятна? public rCanvas : TCanvas; rMoving : Boolean; // - определяем, что текущий рисуемый примитив - двигается constructor Create(const aCanvas : TCanvas); end;//TmsDrawContext TmsMakeShapeContext = record public rStartPoint: TPointF; rShapesController: ImsShapesController; constructor Create(aStartPoint: TPointF; const aShapesController: ImsShapesController); end;//TmsMakeShapeContext TmsEndShapeContext = TmsMakeShapeContext; TmsDrawOptionsContext = record public rFillColor: TAlphaColor; rStrokeDash: TStrokeDash; rStrokeColor: TAlphaColor; rStrokeThickness: Single; constructor Create(const aCtx: TmsDrawContext); end;//TmsDrawOptionsContext ImsDiagramm = interface; TmsDiagrammsEnumerator = TEnumerator; ImsShapesProvider = interface(ImsPersistent) procedure ShapesForToolbarToList(aList: TStrings); end;//ImsShapesProvider ImsDiagrammsList = interface(ImsShapesProvider) function GetEnumerator: TmsDiagrammsEnumerator; function IndexOf(const anItem: ImsDiagramm): Integer; function AddNewDiagramm: ImsDiagramm; procedure AddDiagramm(const aDiagramm: ImsDiagramm); function SelectDiagramm(const aDiagrammName: String): ImsDiagramm; end;//ImsDiagrammsList ImsShape = interface(ImsDiagrammsList) ['{70D5F6A0-1025-418B-959B-0CF524D8E394}'] procedure DrawTo(const aCtx: TmsDrawContext); function IsNeedsSecondClick : Boolean; procedure EndTo(const aCtx: TmsEndShapeContext); function ContainsPt(const aPoint: TPointF): Boolean; procedure MoveTo(const aFinishPoint: TPointF); function pm_GetStartPoint: TPointF; property StartPoint: TPointF read pm_GetStartPoint; end;//ImsShape TmsShapesEnumerator = TEnumerator ; ImsShapeCreator = interface function CreateShape(const aContext: TmsMakeShapeContext): ImsShape; end;//ImsShapeCreator ImsDiagrammsHolder = interface function pm_GetCurrentDiagramms: ImsDiagrammsList; procedure pm_SetCurrentDiagramms(const aValue: ImsDiagrammsList); property CurrentDiagramms : ImsDiagrammsList read pm_GetCurrentDiagramms write pm_SetCurrentDiagramms; end;//ImsDiagrammsHolder TmsClickContext = record public rShapeCreator: ImsShapeCreator; rClickPoint: TPointF; rDiagrammsHolder : ImsDiagrammsHolder; constructor Create(const aShapeCreator: ImsShapeCreator; const aClickPoint: TPointF; const aDiagrammsHolder : ImsDiagrammsHolder); end;//TmsClickContext ImsDiagramm = interface(ImsShapesProvider) ['{59F2D068-F06F-4378-9ED4-888DFE8DFAF2}'] function Get_Name: String; procedure Invalidate; procedure ProcessClick(const aClickContext: TmsClickContext); procedure Clear; procedure DrawTo(const aCanvas: TCanvas); function AddShape(const aShape: ImsShape): ImsShape; function GetEnumerator: TmsShapesEnumerator; function ItemsCount: Integer; property Name: String read Get_Name; end;//ImsDiagramm ImsDiagramms = interface(ImsDiagrammsList) ['{819BEEBA-97BB-48F1-906E-107E67706D19}'] procedure Serialize; procedure DeSerialize; end;//ImsDiagramms ImsIvalidator = interface procedure InvalidateDiagramm(const aDiagramm: ImsDiagramm); procedure DiagrammAdded(const aDiagramms: ImsDiagrammsList; const aDiagramm: ImsDiagramm); end;//ImsIvalidator ImsDiagrammsController = interface procedure Clear; procedure DrawTo(const aCanvas: TCanvas); end;//ImsDiagrammsController implementation // TmsDrawContext constructor TmsDrawContext.Create(const aCanvas : TCanvas); begin rCanvas := aCanvas; rMoving := false; end; // TmsMakeShapeContext constructor TmsMakeShapeContext.Create(aStartPoint: TPointF; const aShapesController: ImsShapesController); begin rStartPoint := aStartPoint; rShapesController := aShapesController; end; // TmsDrawOptionsContext constructor TmsDrawOptionsContext.Create(const aCtx: TmsDrawContext); begin rFillColor := TAlphaColorRec.Null; if aCtx.rMoving then begin rStrokeDash := TStrokeDash.sdDashDot; rStrokeColor := TAlphaColors.Darkmagenta; rStrokeThickness := 4; end//aCtx.rMoving else begin rStrokeDash := TStrokeDash.sdSolid; rStrokeColor := TAlphaColorRec.Black; rStrokeThickness := 1; end;//aCtx.rMoving end; // TmsClickContext constructor TmsClickContext.Create(const aShapeCreator: ImsShapeCreator; const aClickPoint: TPointF; const aDiagrammsHolder : ImsDiagrammsHolder); begin rShapeCreator := aShapeCreator; rClickPoint := aClickPoint; rDiagrammsHolder := aDiagrammsHolder; end; end. ... unit msDiagrammsController; interface uses {$Include msIvalidator.mixin.pas} , FMX.Objects, FMX.ListBox, FMX.StdCtrls, FMX.Graphics, msDiagramms, System.Types, FMX.Forms, System.Classes, System.UITypes, msCoreObjects, msInterfacedRefcounted, msShape, msInterfaces ; type TmsIvalidatorParent = TmsInterfacedRefcounted; {$Include msIvalidator.mixin.pas} TmsDiagrammsController = class(TmsIvalidator, ImsDiagrammsController) private imgMain: TPaintBox; cbShapes: TComboBox; cbDiagramm: TComboBox; btAddDiagramm: TButton; btSaveDiagramm: TButton; btLoadDiagramm: TButton; f_DiagrammsRoot: ImsDiagramms; f_CurrentDiagramms : ImsDiagrammsList; f_CurrentDiagramm : ImsDiagramm; procedure cbDiagrammChange(Sender: TObject); procedure btAddDiagrammClick(Sender: TObject); procedure imgMainMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); procedure btSaveDiagrammClick(Sender: TObject); procedure btLoadDiagrammClick(Sender: TObject); function pm_GetCurrentDiagramm: ImsDiagramm; procedure pm_SetCurrentDiagramm(const aValue: ImsDiagramm); function pm_GetCurrentDiagramms: ImsDiagrammsList; procedure pm_SetCurrentDiagramms(const aValue: ImsDiagrammsList); protected procedure DoInvalidateDiagramm(const aDiagramm: ImsDiagramm); override; procedure DoDiagrammAdded(const aDiagramms: ImsDiagrammsList; const aDiagramm: ImsDiagramm); override; property CurrentDiagramms : ImsDiagrammsList read pm_GetCurrentDiagramms write pm_SetCurrentDiagramms; public constructor Create(aImage: TPaintBox; aShapes: TComboBox; aDiagramm: TComboBox; aAddDiagramm: TButton; aSaveDiagramm: TButton; aLoadDiagramm: TButton); destructor Destroy; override; procedure Clear; procedure ProcessClick(const aStart: TPointF); property CurrentDiagramm: ImsDiagramm read pm_GetCurrentDiagramm write pm_SetCurrentDiagramm; procedure DrawTo(const aCanvas: TCanvas); end;//TmsDiagrammsController implementation uses {$Include msIvalidator.mixin.pas} , System.SysUtils, FMX.Types, msShapesForToolbar, Math, msShapeCreator ; type TmsDiagrammsHolder = class(TmsInterfacedRefcounted, ImsDiagrammsHolder) private f_DiagrammsController : TmsDiagrammsController; constructor CreatePrim(aDiagrammsController : TmsDiagrammsController); protected function pm_GetCurrentDiagramms: ImsDiagrammsList; procedure pm_SetCurrentDiagramms(const aValue: ImsDiagrammsList); public class function Create(aDiagrammsController : TmsDiagrammsController): ImsDiagrammsHolder; end;//TmsDiagrammsHolder constructor TmsDiagrammsHolder.CreatePrim(aDiagrammsController : TmsDiagrammsController); begin inherited Create; f_DiagrammsController := aDiagrammsController; end; class function TmsDiagrammsHolder.Create(aDiagrammsController : TmsDiagrammsController): ImsDiagrammsHolder; begin Result := CreatePrim(aDiagrammsController); end; function TmsDiagrammsHolder.pm_GetCurrentDiagramms: ImsDiagrammsList; begin Result := f_DiagrammsController.CurrentDiagramms; end; procedure TmsDiagrammsHolder.pm_SetCurrentDiagramms(const aValue: ImsDiagrammsList); begin f_DiagrammsController.CurrentDiagramms := aValue; end; {$Include msIvalidator.mixin.pas} // TmsDiagrammsController constructor TmsDiagrammsController.Create(aImage: TPaintBox; aShapes: TComboBox; aDiagramm: TComboBox; aAddDiagramm: TButton; aSaveDiagramm: TButton; aLoadDiagramm: TButton); begin inherited Create; imgMain := aImage; cbShapes := aShapes; cbDiagramm := aDiagramm; btAddDiagramm := aAddDiagramm; btSaveDiagramm := aSaveDiagramm; btLoadDiagramm := aLoadDiagramm; cbDiagramm.OnChange := cbDiagrammChange; btAddDiagramm.OnClick := btAddDiagrammClick; btSaveDiagramm.OnClick := btSaveDiagrammClick; btLoadDiagramm.OnClick := btLoadDiagrammClick; imgMain.OnMouseDown := imgMainMouseDown; imgMain.Align := TAlignLayout.alClient; f_DiagrammsRoot := TmsDiagramms.Create; CurrentDiagramms := f_DiagrammsRoot; CurrentDiagramms.AddNewDiagramm; end; procedure TmsDiagrammsController.DoInvalidateDiagramm(const aDiagramm: ImsDiagramm); begin if (imgMain <> nil) then if (aDiagramm.EQ(CurrentDiagramm)) then imgMain.Repaint; end; function TmsDiagrammsController.pm_GetCurrentDiagramm: ImsDiagramm; begin Result := f_CurrentDiagramm; end; procedure TmsDiagrammsController.pm_SetCurrentDiagramm(const aValue: ImsDiagramm); begin if not aValue.EQ(f_CurrentDiagramm) then begin f_CurrentDiagramm := aValue; cbDiagramm.ItemIndex := cbDiagramm.Items.IndexOf(aValue.Name); f_CurrentDiagramm.Invalidate; end;//not aValue.EQ(f_CurrentDiagramm) end; function TmsDiagrammsController.pm_GetCurrentDiagramms: ImsDiagrammsList; begin Result := f_CurrentDiagramms; end; procedure TmsDiagrammsController.pm_SetCurrentDiagramms(const aValue: ImsDiagrammsList); var l_Index : Integer; begin if (f_CurrentDiagramms <> aValue) then begin f_CurrentDiagramms := aValue; l_Index := cbShapes.ItemIndex; cbShapes.Items.Clear; if (f_CurrentDiagramms <> nil) then begin f_CurrentDiagramms.ShapesForToolbarToList(cbShapes.Items); if (l_Index < 0) then if (cbShapes.Count > 0) then l_Index := 0; cbShapes.ItemIndex := Min(cbShapes.Count-1, l_Index); end;//f_CurrentDiagramms <> nil end;//f_CurrentDiagramms <> aValue end; procedure TmsDiagrammsController.btLoadDiagrammClick(Sender: TObject); var l_D : ImsDiagramm; l_I : Integer; begin l_I := cbDiagramm.ItemIndex; f_DiagrammsRoot.DeSerialize; cbDiagramm.Clear; Assert(f_DiagrammsRoot.EQ(CurrentDiagramms)); for l_D in f_DiagrammsRoot do cbDiagramm.Items.Add(l_D.Name); cbDiagramm.ItemIndex := l_I; end; procedure TmsDiagrammsController.btSaveDiagrammClick(Sender: TObject); begin f_DiagrammsRoot.Serialize; end; procedure TmsDiagrammsController.cbDiagrammChange(Sender: TObject); begin CurrentDiagramm := CurrentDiagramms.SelectDiagramm(cbDiagramm.Items[cbDiagramm.ItemIndex]); CurrentDiagramm.Invalidate; end; procedure TmsDiagrammsController.btAddDiagrammClick(Sender: TObject); begin CurrentDiagramms.AddNewDiagramm; end; destructor TmsDiagrammsController.Destroy; begin f_CurrentDiagramm := nil; CurrentDiagramms := nil; f_DiagrammsRoot := nil; inherited; end; procedure TmsDiagrammsController.Clear; begin CurrentDiagramm.Clear; end; procedure TmsDiagrammsController.ProcessClick(const aStart: TPointF); begin CurrentDiagramm.ProcessClick(TmsClickContext.Create(TmsShapeCreator.Create(TmsShapesForToolbar.Instance.Items[cbShapes.ItemIndex]), aStart, TmsDiagrammsHolder.Create(Self))); end; procedure TmsDiagrammsController.DrawTo(const aCanvas: TCanvas); begin CurrentDiagramm.DrawTo(aCanvas); end; procedure TmsDiagrammsController.imgMainMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin Self.ProcessClick(TPointF.Create(X, Y)); end; procedure TmsDiagrammsController.DoDiagrammAdded(const aDiagramms: ImsDiagrammsList; const aDiagramm: ImsDiagramm); begin Assert(CurrentDiagramms <> nil); if not CurrentDiagramms.EQ(aDiagramms) then Exit; if (CurrentDiagramms <> nil) then begin if (CurrentDiagramms.IndexOf(aDiagramm) >= 0) then begin cbDiagramm.Items.Add(aDiagramm.Name); CurrentDiagramm := aDiagramm; end;//CurrentDiagramms.IndexOf(aDiagramm) >= 0 end;//CurrentDiagramms <> nil end; end.
А вообще на Borland и Embarcadero - "у меня давно зуб".
Комментариев нет:
Отправить комментарий