From a60c185db1f0a3e39e6f3302eeb4e57988ebf8cf Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Thu, 4 Jan 2007 19:47:47 +0000 Subject: [PATCH] Fixed: memory leak in CreateImage method Changed: GraphicList now uses TComponent-based items to support Visual Inheritance --- Packages/X2CLGLEditors.pas | 104 ++--- Packages/X2CLGLReg.pas | 5 +- Packages/X2CLGraphicsEditor.dfm | 358 +++++++++++++---- Packages/X2CLGraphicsEditor.pas | 139 ++++--- Source/X2CLGraphicList.pas | 675 ++++++++++++++++++++++---------- Test/Forms/FMainGL.pas | 1 - 6 files changed, 895 insertions(+), 387 deletions(-) diff --git a/Packages/X2CLGLEditors.pas b/Packages/X2CLGLEditors.pas index e4a3a9d..a1b1238 100644 --- a/Packages/X2CLGLEditors.pas +++ b/Packages/X2CLGLEditors.pas @@ -13,16 +13,9 @@ uses DesignIntf; type - TX2GraphicsProperty = class(TClassProperty) - public - function AllEqual(): Boolean; override; - procedure Edit(); override; - function GetAttributes(): TPropertyAttributes; override; - end; - TX2GraphicContainerEditor = class(TComponentEditor) - private - procedure FindGraphics(const Prop: IProperty); + protected + procedure Convert(); public procedure Edit(); override; procedure ExecuteVerb(Index: Integer); override; @@ -44,62 +37,75 @@ uses X2CLGraphicList, X2CLGraphicsEditor; - -{==================== TX2GraphicsProperty - Editor -========================================} -function TX2GraphicsProperty.AllEqual; -begin - Result := (PropCount = 1); -end; - -procedure TX2GraphicsProperty.Edit; -begin - TfrmGraphicsEditor.Execute(TComponent(GetComponent(0))); -end; - -function TX2GraphicsProperty.GetAttributes; -begin - Result := [paDialog, paReadOnly]; -end; +type + TProtectedX2GraphicContainer = class(TX2GraphicContainer); {============== TX2GraphicContainerEditor Editor ========================================} -procedure TX2GraphicContainerEditor.FindGraphics; +procedure TX2GraphicContainerEditor.Edit(); begin - if SameText(Prop.GetName(), 'Graphics') then - Prop.Edit(); + TfrmGraphicsEditor.Execute(Component, Self.Designer); end; -procedure TX2GraphicContainerEditor.Edit; -var - dsComponents: TDesignerSelections; - +procedure TX2GraphicContainerEditor.ExecuteVerb(Index: Integer); begin - dsComponents := TDesignerSelections.Create(); - try - IDesignerSelections(dsComponents).Add(Component); - GetComponentProperties(dsComponents, tkProperties, Designer, FindGraphics); - finally - FreeAndNil(dsComponents); + case Index of + 0: Edit(); + 1: Convert(); end; end; -procedure TX2GraphicContainerEditor.ExecuteVerb; +function TX2GraphicContainerEditor.GetVerb(Index: Integer): String; begin - Edit(); + case Index of + 0: Result := 'Graphics Editor...'; + 1: Result := 'Convert items'; + end; end; -function TX2GraphicContainerEditor.GetVerb; -begin - Result := 'Graphics Editor...'; -end; - -function TX2GraphicContainerEditor.GetVerbCount; +function TX2GraphicContainerEditor.GetVerbCount(): Integer; begin Result := 1; + + if TProtectedX2GraphicContainer(Component).ConversionRequired then + Inc(Result); +end; + + +procedure TX2GraphicContainerEditor.Convert(); +var + container: TX2GraphicContainer; + tempContainer: TX2GraphicContainer; + graphicIndex: Integer; + graphicItem: TX2GraphicContainerItem; + +begin + if not Assigned(Designer) then + exit; + + container := TX2GraphicContainer(Component); + tempContainer := TX2GraphicContainer.Create(nil); + try + tempContainer.Assign(container); + + container.Clear(); + + for graphicIndex := 0 to Pred(tempContainer.GraphicCount) do + begin + graphicItem := TX2GraphicContainerItem(Designer.CreateComponent(TX2GraphicContainerItem, nil, 0, 0, 0, 0)); + if Assigned(graphicItem) then + begin + graphicItem.Assign(tempContainer.Graphics[graphicIndex]); + graphicItem.Container := container; + end; + end; + + TProtectedX2GraphicContainer(container).ConversionRequired := False; + finally + FreeAndNil(tempContainer); + end; end; @@ -124,4 +130,4 @@ begin end; end. - \ No newline at end of file + diff --git a/Packages/X2CLGLReg.pas b/Packages/X2CLGLReg.pas index f3aa4f0..b1e0586 100644 --- a/Packages/X2CLGLReg.pas +++ b/Packages/X2CLGLReg.pas @@ -21,12 +21,13 @@ uses procedure Register; begin + RegisterNoIcon([TX2GraphicContainerItem]); + RegisterComponents('X2Software', [TX2GraphicContainer, TX2GraphicList]); - RegisterPropertyEditor(TypeInfo(TX2GraphicCollection), TX2GraphicContainer, 'Graphics', TX2GraphicsProperty); RegisterComponentEditor(TX2GraphicContainer, TX2GraphicContainerEditor); RegisterComponentEditor(TX2GraphicList, TX2GraphicListEditor); end; end. - \ No newline at end of file + diff --git a/Packages/X2CLGraphicsEditor.dfm b/Packages/X2CLGraphicsEditor.dfm index 0b453a2..85bb866 100644 --- a/Packages/X2CLGraphicsEditor.dfm +++ b/Packages/X2CLGraphicsEditor.dfm @@ -20,13 +20,13 @@ object frmGraphicsEditor: TfrmGraphicsEditor Left = 189 Top = 0 Width = 4 - Height = 424 + Height = 422 end object pnlImage: TPanel Left = 193 Top = 0 Width = 333 - Height = 424 + Height = 422 Align = alClient BevelOuter = bvNone TabOrder = 1 @@ -60,7 +60,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor Left = 0 Top = 26 Width = 333 - Height = 370 + Height = 368 Align = alClient BevelInner = bvNone BevelKind = bkTile @@ -78,7 +78,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor end object pnlProperties: TPanel Left = 0 - Top = 396 + Top = 394 Width = 333 Height = 28 Align = alBottom @@ -110,7 +110,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor Left = 0 Top = 0 Width = 189 - Height = 424 + Height = 422 Align = alLeft BevelOuter = bvNone TabOrder = 0 @@ -118,7 +118,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor Left = 0 Top = 26 Width = 189 - Height = 398 + Height = 396 Align = alClient ItemHeight = 13 TabOrder = 1 @@ -168,7 +168,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor Top = 388 Bitmap = { 494C010107000900040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 - 0000000000003600000028000000400000003000000001001000000000000018 + 0000000000003600000028000000400000003000000001002000000000000030 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -250,37 +250,14 @@ object frmGraphicsEditor: TfrmGraphicsEditor 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000000000000 - 1002000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000010021002 - 1002100210020000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000100210021002 - 1002100210021002000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000100210021002 - 1002100210021002000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000010021002 - 1002100210020000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 1002000000000000000000000000000000000000000000000000000000001002 - 1002100200000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -301,63 +278,278 @@ object frmGraphicsEditor: TfrmGraphicsEditor 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000010421042104210421042 - 1042104210421042104210421042104210420000000010421042104210421042 - 1042104210421042104210421042104210420000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000010420000000000000000000000000000 - 0000000000000000000000000000000010420000000000000000000000000000 - 0000000000000000000000000000000000000000000000420042000000000000 - 00000000000000000000000000420000000000000000FF7FE07FFF7FE07FFF7F - E07FFF7FE07F00000000FF7FE07F0000104200000000FF7FE07FFF7FE07FFF7F - E07FFF7FE07F00000000FF7FE07F000010420000000000000000000000000000 - 0000000000000000000000000000000000000000000000420042000000000000 - 00000000000000000000000000420000000000000000E07FFF7FE07FFF7FE07F - FF7FE07FFF7F000018630000FF7F0000104210420000E07FFF7FE07FFF7FE07F - FF7FE07FFF7F000018630000FF7F000010420000000000420042004200420042 - 0042004200420042000000000000000000000000000000420042000000000000 - 00000000000000000000000000420000000000000000FF7FE07FFF7FE07FFF7F - E07FFF7FE07F0000E07F186300000000104200400000FF7FE07FFF7FE07FFF7F - E07FFF7FE07F0000E07F18630000000010420000FF7F00000042004200420042 - 0042004200420042004200000000000000000000000000420042000000000000 - 00000000000000000000000000420000000000000000E07FFF7FE07FFF7FE07F - FF7FE07FFF7F00000000000000000000104200400040E07FFF7FE07FFF7F1042 - 0040E07FFF7F0000000000000000000010420000E07FFF7F0000004200420042 - 0042004200420042004200420000000000000000000000420042004200420042 - 00420042004200420042004200420000000000000000FF7F1042E07FFF7FE07F - FF7FE07FE07FFF7FE07FFF7FE07F00001042104200401042E07FFF7F10420040 - 1042FF7FE07FFF7FE07FFF7FE07F000010420000FF7FE07FFF7F000000420042 - 0042004200420042004200420042000000000000000000420042000000000000 - 0000000000000000000000420042000000001042E07FE07F1042FF7FE07F1042 - E07FFF7FFF7FE07FFF7FE07FFF7F000010420000004000401042E07F00400040 - FF7FE07FFF7FE07FFF7FE07FFF7F000010420000E07FFF7FE07FFF7F00000000 - 0000000000000000000000000000000000000000000000420000000000000000 - 00000000000000000000000000420000000000001042FF7F1042E07F1042E07F - FF7FE07FE07FFF7FE07FFF7FE07F00001042000010420040004000400040FF7F - E07FFF7FE07FFF7FE07FFF7FE07F000010420000FF7FE07FFF7FE07FFF7FE07F - FF7FE07FFF7F0000000000000000000000000000000000420000000000000000 - 000000000000000000000000004200000000104210421042FF7F1042FF7FE07F - FF7FE07FFF7FE07FFF7FE07FFF7F0000104200001042004000400040FF7FE07F - FF7FE07FFF7FE07FFF7FE07FFF7F000010420000E07FFF7FE07FFF7FE07FFF7F - E07FFF7FE07F0000000000000000000000000000000000420000000000000000 - 0000000000000000000000000042000000000000E07F1042E07FFF7F10421042 - 1042104200000000000000000000000000001042004000400040004010420000 - 0000000000000000000000000000000000000000FF7FE07FFF7F000000000000 - 0000000000000000000000000000000000000000000000420000000000000000 - 00000000000000000000000000420000000000001042E07F1042E07F1042E07F - 0000000000000000000000000000000000000040004010420000004000401042 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000420000000000000000 - 0000000000000000000000000000000000001042E07F00001042000000001042 - E07F000000000000000000000000000000000000000000000000000000400040 - 1042000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000420000000000000000 - 000000000000000000000000000000000000E07F000000001042E07F00000000 - 1042000000000000000000000000000000000000000000000000000000000040 - 0040104200000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000001042000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000848400000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008484000084840000848400008484000084840000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000848400008484000084840000848400008484000084840000848400000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000848400008484000084840000848400008484000084840000848400000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008484000084840000848400008484000084840000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000848400000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000084840000848400008484000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000848484008484 + 8400848484008484840084848400848484008484840084848400848484008484 + 8400848484008484840084848400848484000000000000000000848484008484 + 8400848484008484840084848400848484008484840084848400848484008484 + 8400848484008484840084848400848484000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000848484000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000848484000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008484000084 + 8400000000000000000000000000000000000000000000000000000000000000 + 0000000000000084840000000000000000000000000000000000FFFFFF0000FF + FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00000000000000 + 0000FFFFFF0000FFFF0000000000848484000000000000000000FFFFFF0000FF + FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00000000000000 + 0000FFFFFF0000FFFF0000000000848484000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008484000084 + 8400000000000000000000000000000000000000000000000000000000000000 + 000000000000008484000000000000000000000000000000000000FFFF00FFFF + FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000000000C6C6 + C60000000000FFFFFF000000000084848400848484000000000000FFFF00FFFF + FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000000000C6C6 + C60000000000FFFFFF0000000000848484000000000000000000008484000084 + 8400008484000084840000848400008484000084840000848400008484000000 + 0000000000000000000000000000000000000000000000000000008484000084 + 8400000000000000000000000000000000000000000000000000000000000000 + 0000000000000084840000000000000000000000000000000000FFFFFF0000FF + FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF000000000000FF + FF00C6C6C6000000000000000000848484000000840000000000FFFFFF0000FF + FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF000000000000FF + FF00C6C6C60000000000000000008484840000000000FFFFFF00000000000084 + 8400008484000084840000848400008484000084840000848400008484000084 + 8400000000000000000000000000000000000000000000000000008484000084 + 8400000000000000000000000000000000000000000000000000000000000000 + 000000000000008484000000000000000000000000000000000000FFFF00FFFF + FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF00000000000000 + 000000000000000000000000000084848400000084000000840000FFFF00FFFF + FF0000FFFF00FFFFFF00848484000000840000FFFF00FFFFFF00000000000000 + 0000000000000000000000000000848484000000000000FFFF00FFFFFF000000 + 0000008484000084840000848400008484000084840000848400008484000084 + 8400008484000000000000000000000000000000000000000000008484000084 + 8400008484000084840000848400008484000084840000848400008484000084 + 8400008484000084840000000000000000000000000000000000FFFFFF008484 + 840000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF0000FFFF00FFFFFF0000FF + FF00FFFFFF0000FFFF00000000008484840084848400000084008484840000FF + FF00FFFFFF00848484000000840084848400FFFFFF0000FFFF00FFFFFF0000FF + FF00FFFFFF0000FFFF00000000008484840000000000FFFFFF0000FFFF00FFFF + FF00000000000084840000848400008484000084840000848400008484000084 + 8400008484000084840000000000000000000000000000000000008484000084 + 8400000000000000000000000000000000000000000000000000000000000000 + 0000008484000084840000000000000000008484840000FFFF0000FFFF008484 + 8400FFFFFF0000FFFF008484840000FFFF00FFFFFF00FFFFFF0000FFFF00FFFF + FF0000FFFF00FFFFFF0000000000848484000000000000008400000084008484 + 840000FFFF000000840000008400FFFFFF0000FFFF00FFFFFF0000FFFF00FFFF + FF0000FFFF00FFFFFF0000000000848484000000000000FFFF00FFFFFF0000FF + FF00FFFFFF000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008484000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000084840000000000000000000000000084848400FFFFFF008484 + 840000FFFF008484840000FFFF00FFFFFF0000FFFF0000FFFF00FFFFFF0000FF + FF00FFFFFF0000FFFF0000000000848484000000000084848400000084000000 + 84000000840000008400FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FF + FF00FFFFFF0000FFFF00000000008484840000000000FFFFFF0000FFFF00FFFF + FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF00000000000000 + 0000000000000000000000000000000000000000000000000000008484000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000008484000000000000000000848484008484840084848400FFFF + FF0084848400FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFF + FF0000FFFF00FFFFFF0000000000848484000000000084848400000084000000 + 840000008400FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFF + FF0000FFFF00FFFFFF0000000000848484000000000000FFFF00FFFFFF0000FF + FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00000000000000 + 0000000000000000000000000000000000000000000000000000008484000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000084840000000000000000000000000000FFFF008484840000FF + FF00FFFFFF008484840084848400848484008484840000000000000000000000 + 0000000000000000000000000000000000008484840000008400000084000000 + 8400000084008484840000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000FFFFFF0000FFFF00FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008484000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000008484000000000000000000000000008484840000FFFF008484 + 840000FFFF008484840000FFFF00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000840000008400848484000000 + 0000000084000000840084848400000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008484000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000008484840000FFFF00000000008484 + 840000000000000000008484840000FFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000840000008400848484000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000008484000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000FFFF0000000000000000008484 + 840000FFFF000000000000000000848484000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000008400000084008484840000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000008484 + 8400000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/Packages/X2CLGraphicsEditor.pas b/Packages/X2CLGraphicsEditor.pas index af6953b..1187b13 100644 --- a/Packages/X2CLGraphicsEditor.pas +++ b/Packages/X2CLGraphicsEditor.pas @@ -13,6 +13,7 @@ uses Classes, ComCtrls, Controls, + DesignIntf, Dialogs, ExtCtrls, ExtDlgs, @@ -68,15 +69,17 @@ type procedure actClearExecute(Sender: TObject); private FComponent: TX2GraphicContainer; + FComponentDesigner: IDesigner; - procedure InternalExecute(const AComponent: TComponent); + procedure InternalExecute(const AComponent: TComponent; const ADesigner: IDesigner); procedure Administrate(); procedure UpdatePreview(); - function Active(out AIndex: Integer; - out AGraphic: TX2GraphicCollectionItem): Boolean; + function Active(out AIndex: Integer; out AGraphic: TX2GraphicContainerItem): Boolean; + protected + procedure Notification(AComponent: TComponent; Operation: TOperation); override; public - class procedure Execute(const AComponent: TComponent); + class procedure Execute(const AComponent: TComponent; const ADesigner: IDesigner); end; implementation @@ -94,21 +97,24 @@ var {===================== TfrmGraphicsEditor Initialization ========================================} -class procedure TfrmGraphicsEditor.Execute; +class procedure TfrmGraphicsEditor.Execute(const AComponent: TComponent; const ADesigner: IDesigner); begin if not Assigned(GEditor) then GEditor := TfrmGraphicsEditor.Create(Application); - GEditor.InternalExecute(AComponent); + GEditor.InternalExecute(AComponent, ADesigner); end; -procedure TfrmGraphicsEditor.InternalExecute; +procedure TfrmGraphicsEditor.InternalExecute(const AComponent: TComponent; const ADesigner: IDesigner); var iGraphic: Integer; begin - FComponent := TX2GraphicContainer(AComponent); - Caption := Format('%s.Graphics', [FComponent.Name]); + FComponent := TX2GraphicContainer(AComponent); + FComponent.FreeNotification(Self); + + FComponentDesigner := ADesigner; + Caption := Format('%s Graphics', [FComponent.Name]); // Fill graphics list with lstGraphics.Items do @@ -117,8 +123,8 @@ begin try Clear(); - for iGraphic := 0 to FComponent.Graphics.Count - 1 do - AddObject(FComponent.Graphics[iGraphic].DisplayName, + for iGraphic := 0 to FComponent.GraphicCount - 1 do + AddObject(FComponent.Graphics[iGraphic].PictureName, FComponent.Graphics[iGraphic]); finally EndUpdate(); @@ -132,18 +138,21 @@ begin Show(); end; -procedure TfrmGraphicsEditor.FormClose; +procedure TfrmGraphicsEditor.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; GEditor := nil; + + if Assigned(FComponent) then + FComponent.RemoveFreeNotification(Self); end; -procedure TfrmGraphicsEditor.Administrate; +procedure TfrmGraphicsEditor.Administrate(); var bEnabled: Boolean; iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin bEnabled := Active(iIndex, pGraphic); @@ -162,18 +171,23 @@ begin actDown.Enabled := bEnabled and (iIndex < lstGraphics.Items.Count - 1); end; -procedure TfrmGraphicsEditor.UpdatePreview; +procedure TfrmGraphicsEditor.UpdatePreview(); var iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin if Active(iIndex, pGraphic) then begin imgPreview.Picture.Assign(pGraphic.Picture); - txtName.Text := pGraphic.Name; + txtName.Text := pGraphic.PictureName; Administrate(); - end; + + if Assigned(FComponentDesigner) then + FComponentDesigner.SelectComponent(pGraphic); + end else + if Assigned(FComponentDesigner) then + FComponentDesigner.SelectComponent(FComponent); end; @@ -181,63 +195,76 @@ end; {===================== TfrmGraphicsEditor Graphic Management ========================================} -function TfrmGraphicsEditor.Active; +function TfrmGraphicsEditor.Active(out AIndex: Integer; out AGraphic: TX2GraphicContainerItem): Boolean; begin Result := False; AIndex := lstGraphics.ItemIndex; if AIndex = -1 then exit; - AGraphic := TX2GraphicCollectionItem(lstGraphics.Items.Objects[AIndex]); + AGraphic := TX2GraphicContainerItem(lstGraphics.Items.Objects[AIndex]); Result := Assigned(AGraphic); end; -procedure TfrmGraphicsEditor.lstGraphicsClick; +procedure TfrmGraphicsEditor.lstGraphicsClick(Sender: TObject); begin UpdatePreview(); end; -procedure TfrmGraphicsEditor.txtNameChange; +procedure TfrmGraphicsEditor.txtNameChange(Sender: TObject); var iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin if Active(iIndex, pGraphic) then begin - pGraphic.Name := txtName.Text; - lstGraphics.Items[iIndex] := pGraphic.DisplayName; + pGraphic.PictureName := txtName.Text; + lstGraphics.Items[iIndex] := pGraphic.PictureName; end; end; -procedure TfrmGraphicsEditor.actAddExecute; +procedure TfrmGraphicsEditor.actAddExecute(Sender: TObject); var iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin - pGraphic := FComponent.Graphics.Add(); - iIndex := lstGraphics.Items.AddObject(pGraphic.DisplayName, - pGraphic); + if Assigned(FComponentDesigner) then + begin + pGraphic := TX2GraphicContainerItem(FComponentDesigner.CreateComponent(TX2GraphicContainerItem, nil, 0, 0, 0, 0)); - lstGraphics.ItemIndex := iIndex; - UpdatePreview(); - - actOpen.Execute(); + if Assigned(pGraphic) then + begin + pGraphic.Container := FComponent; + iIndex := lstGraphics.Items.AddObject(pGraphic.PictureName, + pGraphic); + + lstGraphics.ItemIndex := iIndex; + UpdatePreview(); + + actOpen.Execute(); + end else + raise Exception.Create('Failed to create TX2GraphicContainerItem!'); + end else + raise Exception.Create('Designer not found!'); end; -procedure TfrmGraphicsEditor.actDeleteExecute; +procedure TfrmGraphicsEditor.actDeleteExecute(Sender: TObject); var iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin if Active(iIndex, pGraphic) then begin + { First attempt to remove the component; this will raise an exception + if it's not allowed, for example due to it being introduced in + an ancestor. } + pGraphic.Free(); lstGraphics.Items.Delete(iIndex); - FComponent.Graphics.Delete(pGraphic.Index); if iIndex > lstGraphics.Items.Count - 1 then iIndex := lstGraphics.Items.Count - 1; @@ -247,10 +274,10 @@ begin end; end; -procedure TfrmGraphicsEditor.actUpExecute; +procedure TfrmGraphicsEditor.actUpExecute(Sender: TObject); var iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin if Active(iIndex, pGraphic) then @@ -263,10 +290,10 @@ begin end; end; -procedure TfrmGraphicsEditor.actDownExecute; +procedure TfrmGraphicsEditor.actDownExecute(Sender: TObject); var iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin if Active(iIndex, pGraphic) then @@ -280,10 +307,10 @@ begin end; -procedure TfrmGraphicsEditor.actOpenExecute; +procedure TfrmGraphicsEditor.actOpenExecute(Sender: TObject); var iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin if Active(iIndex, pGraphic) then @@ -292,36 +319,36 @@ begin if dlgOpen.Execute() then begin pGraphic.Picture.LoadFromFile(dlgOpen.FileName); - if Length(pGraphic.Name) = 0 then - pGraphic.Name := ChangeFileExt(ExtractFileName(dlgOpen.FileName), ''); + if Length(pGraphic.PictureName) = 0 then + pGraphic.PictureName := ChangeFileExt(ExtractFileName(dlgOpen.FileName), ''); UpdatePreview(); end; end; end; -procedure TfrmGraphicsEditor.actSaveExecute; +procedure TfrmGraphicsEditor.actSaveExecute(Sender: TObject); var iIndex: Integer; pClass: TGraphicClass; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin if Active(iIndex, pGraphic) then if Assigned(pGraphic.Picture.Graphic) then begin pClass := TGraphicClass(pGraphic.Picture.Graphic.ClassType); dlgSave.Filter := GraphicFilter(pClass); - dlgSave.FileName := ChangeFileExt(pGraphic.Name, '.' + GraphicExtension(pClass)); + dlgSave.FileName := ChangeFileExt(pGraphic.PictureName, '.' + GraphicExtension(pClass)); if dlgSave.Execute() then pGraphic.Picture.SaveToFile(dlgSave.FileName); end; end; -procedure TfrmGraphicsEditor.actClearExecute; +procedure TfrmGraphicsEditor.actClearExecute(Sender: TObject); var iIndex: Integer; - pGraphic: TX2GraphicCollectionItem; + pGraphic: TX2GraphicContainerItem; begin if Active(iIndex, pGraphic) then @@ -331,4 +358,16 @@ begin end; end; + +procedure TfrmGraphicsEditor.Notification(AComponent: TComponent; Operation: TOperation); +begin + inherited; + + if (Operation = opRemove) and (AComponent = FComponent) then + begin + FComponent := nil; + Close(); + end; +end; + end. diff --git a/Source/X2CLGraphicList.pas b/Source/X2CLGraphicList.pas index 9215eab..fb5bbc7 100644 --- a/Source/X2CLGraphicList.pas +++ b/Source/X2CLGraphicList.pas @@ -7,7 +7,6 @@ :: the problems I thought we would face. His original (Dutch) article can :: be found at: :: http://www.erikstok.net/delphi/artikelen/xpicons.html - :: :: Last changed: $Date$ :: Revision: $Rev$ :: Author: $Author$ @@ -36,54 +35,42 @@ type { :$ Holds a single graphic. } - TX2GraphicCollectionItem = class(TCollectionItem, IChangeNotifier) + TX2GraphicContainerItem = class(TComponent, IChangeNotifier) private - FName: String; + FContainer: TX2GraphicContainer; FPicture: TPicture; + FPictureName: String; + function GetIndex(): Integer; + procedure SetContainer(const Value: TX2GraphicContainer); + procedure SetIndex(const Value: Integer); procedure SetPicture(const Value: TPicture); - procedure SetName(const Value: String); + procedure SetPictureName(const Value: String); protected - function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; - function _AddRef(): Integer; stdcall; - function _Release(): Integer; stdcall; + procedure Changed(); virtual; + procedure InternalSetContainer(const AContainer: TX2GraphicContainer); virtual; - function GetDisplayName(): String; override; + function GenerateName(): String; procedure NotifierChanged(); procedure IChangeNotifier.Changed = NotifierChanged; + + procedure ReadState(Reader: TReader); override; + procedure SetParentComponent(AParent: TComponent); override; public - constructor Create(Collection: TCollection); override; + constructor Create(AOwner: TComponent); override; destructor Destroy(); override; + function GetParentComponent(): TComponent; override; + function HasParent(): Boolean; override; + procedure AssignTo(Dest: TPersistent); override; - published - property Name: String read FName write SetName; - property Picture: TPicture read FPicture write SetPicture; - end; - - { - :$ Holds a collection of graphics. - } - TX2GraphicCollection = class(TCollection) - private - FContainer: TX2GraphicContainer; - - function GetItem(Index: Integer): TX2GraphicCollectionItem; - procedure SetItem(Index: Integer; Value: TX2GraphicCollectionItem); - protected - procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); override; - procedure Update(Item: TCollectionItem); override; public - constructor Create(const AContainer: TX2GraphicContainer); - - function Add(): TX2GraphicCollectionItem; - function IndexByName(const AName: String): Integer; - function GraphicByName(const AName: String): TX2GraphicCollectionItem; - function PictureByName(const AName: String): TPicture; - - property Items[Index: Integer]: TX2GraphicCollectionItem read GetItem - write SetItem; default; + property Container: TX2GraphicContainer read FContainer write SetContainer stored False; + property Index: Integer read GetIndex write SetIndex stored False; + published + property Picture: TPicture read FPicture write SetPicture; + property PictureName: String read FPictureName write SetPictureName; end; { @@ -94,28 +81,48 @@ type } TX2GraphicContainer = class(TComponent) private - FGraphics: TX2GraphicCollection; - FLists: TList; + FConversionRequired: Boolean; + FGraphics: TList; + FLists: TList; - procedure SetGraphics(const Value: TX2GraphicCollection); + function GetGraphicCount(): Integer; + function GetGraphics(Index: Integer): TX2GraphicContainerItem; + procedure SetGraphics(Index: Integer; const Value: TX2GraphicContainerItem); protected + procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; + procedure SetChildOrder(Component: TComponent; Order: Integer); override; + procedure SetName(const NewName: TComponentName); override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; - procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); virtual; - procedure Update(Item: TCollectionItem); virtual; + + procedure ConvertGraphics(Reader: TReader); + procedure DefineProperties(Filer: TFiler); override; + + procedure AddGraphic(const AGraphic: TX2GraphicContainerItem); virtual; + procedure RemoveGraphic(const AGraphic: TX2GraphicContainerItem); virtual; + procedure UpdateGraphic(const AGraphic: TX2GraphicContainerItem); virtual; procedure RegisterList(const AList: TX2GraphicList); procedure UnregisterList(const AList: TX2GraphicList); + + property ConversionRequired: Boolean read FConversionRequired write FConversionRequired; + + property GraphicsList: TList read FGraphics; + property Lists: TList read FLists; public constructor Create(AOwner: TComponent); override; destructor Destroy(); override; + procedure Clear(); + function IndexByName(const AName: String): Integer; - function GraphicByName(const AName: String): TX2GraphicCollectionItem; + function GraphicByName(const AName: String): TX2GraphicContainerItem; function PictureByName(const AName: String): TPicture; procedure AssignTo(Dest: TPersistent); override; - published - property Graphics: TX2GraphicCollection read FGraphics write SetGraphics; + + property Graphics[Index: Integer]: TX2GraphicContainerItem read GetGraphics write SetGraphics; + property GraphicCount: Integer read GetGraphicCount; end; { @@ -156,7 +163,7 @@ type procedure DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer; Style: Cardinal; Enabled: Boolean = True); override; - procedure CreateImage(const AIndex: Integer; var AImage, AMask: TBitmap); virtual; + procedure BuildImage(const AIndex: Integer; const AImage, AMask: TBitmap); virtual; procedure AddImage(const AIndex: Integer); virtual; procedure UpdateImage(const AIndex: Integer); virtual; procedure DeleteImage(const AIndex: Integer); virtual; @@ -183,6 +190,7 @@ type implementation uses + Forms, ImgList, SysUtils; @@ -194,162 +202,233 @@ type -{=============== TX2GraphicCollectionItem + { Used for conversion purposes from the old collection-based Graphics property + to the new TComponent structure. } + TDeprecatedGraphicItem = class(TCollectionItem) + private + FName: String; + FPicture: TPicture; + + procedure SetPicture(const Value: TPicture); + public + constructor Create(Collection: TCollection); override; + destructor Destroy(); override; + published + property Name: String read FName write FName; + property Picture: TPicture read FPicture write SetPicture; + end; + + + +{================ TX2GraphicContainerItem Initialization ========================================} -constructor TX2GraphicCollectionItem.Create(Collection: TCollection); +constructor TX2GraphicContainerItem.Create(AOwner: TComponent); begin + inherited; + FPicture := TPicture.Create(); FPicture.PictureAdapter := Self; - - inherited; end; -destructor TX2GraphicCollectionItem.Destroy(); +destructor TX2GraphicContainerItem.Destroy(); begin + if Assigned(Container) then + Container.RemoveGraphic(Self); + FreeAndNil(FPicture); inherited; end; -procedure TX2GraphicCollectionItem.AssignTo(Dest: TPersistent); +procedure TX2GraphicContainerItem.AssignTo(Dest: TPersistent); begin - if Dest is TX2GraphicCollectionItem then - with TX2GraphicCollectionItem(Dest) do - Picture := Self.Picture + if Dest is TX2GraphicContainerItem then + with TX2GraphicContainerItem(Dest) do + begin + Picture := Self.Picture; + PictureName := Self.PictureName; + end else inherited; end; -function TX2GraphicCollectionItem.QueryInterface(const IID: TGUID; - out Obj): HResult; +procedure TX2GraphicContainerItem.NotifierChanged(); begin - if GetInterface(IID, Obj) then - Result := 0 + Changed(); +end; + + +procedure TX2GraphicContainerItem.InternalSetContainer(const AContainer: TX2GraphicContainer); +begin + FContainer := AContainer; +end; + + + +procedure TX2GraphicContainerItem.Changed(); +begin + if Assigned(Container) then + Container.UpdateGraphic(Self); +end; + + + +function TX2GraphicContainerItem.GetParentComponent(): TComponent; +begin + if Assigned(Container) then + Result := Container else - Result := E_NOINTERFACE; + Result := inherited GetParentComponent(); end; -function TX2GraphicCollectionItem._AddRef(): Integer; +function TX2GraphicContainerItem.HasParent(): Boolean; begin - Result := -1; -end; - -function TX2GraphicCollectionItem._Release(): Integer; -begin - Result := -1; -end; - - -function TX2GraphicCollectionItem.GetDisplayName(): String; -begin - if Length(FName) > 0 then - Result := FName + if Assigned(Container) then + Result := True else - Result := inherited GetDisplayName(); + Result := inherited HasParent(); end; -procedure TX2GraphicCollectionItem.NotifierChanged(); + +procedure TX2GraphicContainerItem.ReadState(Reader: TReader); begin - Changed(False); + inherited; + + if Reader.Parent is TX2GraphicContainer then + Container := TX2GraphicContainer(Reader.Parent); end; -procedure TX2GraphicCollectionItem.SetName(const Value: String); +procedure TX2GraphicContainerItem.SetParentComponent(AParent: TComponent); begin - FName := Value; - Changed(False); + if not (csLoading in ComponentState) and (AParent is TX2GraphicContainer) then + Container := TX2GraphicContainer(AParent); end; -procedure TX2GraphicCollectionItem.SetPicture(const Value: TPicture); + +function TX2GraphicContainerItem.GetIndex(): Integer; +begin + Result := -1; + if Assigned(Container) then + Result := Container.GraphicsList.IndexOf(Self); +end; + +procedure TX2GraphicContainerItem.SetContainer(const Value: TX2GraphicContainer); +begin + if Value <> Container then + begin + if Assigned(Container) then + Container.RemoveGraphic(Self); + + if Assigned(Value) then + Value.AddGraphic(Self); + + if not (csLoading in ComponentState) then + Name := GenerateName(); + end; +end; + +procedure TX2GraphicContainerItem.SetIndex(const Value: Integer); +var + count: Integer; + curIndex: Integer; + newIndex: Integer; + +begin + curIndex := GetIndex(); + + if curIndex > -1 then + begin + count := Container.GraphicsList.Count; + newIndex := Value; + + if newIndex < 0 then + newIndex := 0; + + if newIndex >= count then + newIndex := Pred(count); + + if newIndex <> curIndex then + Container.GraphicsList.Move(curIndex, newIndex); + end; +end; + +procedure TX2GraphicContainerItem.SetPicture(const Value: TPicture); begin FPicture.Assign(Value); end; - -{=================== TX2GraphicCollection - Item Management -========================================} -constructor TX2GraphicCollection.Create(const AContainer: TX2GraphicContainer); +procedure TX2GraphicContainerItem.SetPictureName(const Value: String); begin - inherited Create(TX2GraphicCollectionItem); + if Value <> FPictureName then + begin + FPictureName := Value; - FContainer := AContainer; + if not (csLoading in ComponentState) then + Name := GenerateName(); + end; end; -function TX2GraphicCollection.Add(): TX2GraphicCollectionItem; -begin - Result := TX2GraphicCollectionItem(inherited Add()); -end; +function TX2GraphicContainerItem.GenerateName(): String; + function ValidComponentName(const AComponent: TComponent; const AName: String): Boolean; + var + checkOwner: TComponent; + existing: TComponent; + begin + Result := True; + checkOwner := AComponent; -function TX2GraphicCollection.IndexByName(const AName: String): Integer; -var - iIndex: Integer; - -begin - Result := -1; - for iIndex := Pred(Count) downto 0 do - if SameText(Items[iIndex].Name, AName) then + while Assigned(checkOwner) do begin - Result := iIndex; - break; + existing := checkOwner.FindComponent(AName); + + if Assigned(existing) and (existing <> Self) then + begin + Result := False; + exit; + end; + + checkOwner := checkOwner.Owner; end; -end; + end; + + +const + Alpha = ['A'..'Z', 'a'..'z', '_']; + AlphaNumeric = Alpha + ['0'..'9']; -function TX2GraphicCollection.GraphicByName(const AName: String): TX2GraphicCollectionItem; var - iIndex: Integer; + charIndex: Integer; + counter: Integer; + resultName: String; + begin - Result := nil; - iIndex := IndexByName(AName); - if iIndex > -1 then - Result := Items[iIndex]; + if Assigned(Container) then + Result := Container.Name + else + Result := 'GraphicContainerItem'; + + for charIndex := 1 to Length(PictureName) do + if PictureName[charIndex] in AlphaNumeric then + Result := Result + PictureName[charIndex]; + + + resultName := Result; + counter := 0; + + while not ValidComponentName(Self, Result) do + begin + Inc(counter); + Result := resultName + IntToStr(counter); + end; end; -function TX2GraphicCollection.PictureByName(const AName: String): TPicture; -var - pGraphic: TX2GraphicCollectionItem; - -begin - Result := nil; - pGraphic := GraphicByName(AName); - if Assigned(pGraphic) then - Result := pGraphic.Picture; -end; - - -procedure TX2GraphicCollection.Notify(Item: TCollectionItem; - Action: TCollectionNotification); -begin - inherited; - - if Assigned(FContainer) then - FContainer.Notify(Item, Action); -end; - -procedure TX2GraphicCollection.Update(Item: TCollectionItem); -begin - inherited; - - if Assigned(FContainer) then - FContainer.Update(Item); -end; - - -function TX2GraphicCollection.GetItem(Index: Integer): TX2GraphicCollectionItem; -begin - Result := TX2GraphicCollectionItem(inherited GetItem(Index)); -end; - -procedure TX2GraphicCollection.SetItem(Index: Integer; Value: TX2GraphicCollectionItem); -begin - inherited SetItem(Index, Value); -end; {==================== TX2GraphicContainer @@ -359,12 +438,14 @@ constructor TX2GraphicContainer.Create(AOwner: TComponent); begin inherited; - FGraphics := TX2GraphicCollection.Create(Self); + FGraphics := TList.Create(); FLists := TList.Create(); end; destructor TX2GraphicContainer.Destroy(); begin + Clear(); + FreeAndNil(FGraphics); FreeAndNil(FLists); @@ -373,95 +454,264 @@ end; function TX2GraphicContainer.IndexByName(const AName: String): Integer; +var + graphicIndex: Integer; + begin - Result := FGraphics.IndexByName(AName); + Result := -1; + + for graphicIndex := Pred(GraphicCount) downto 0 do + if SameText(Graphics[graphicIndex].Name, AName) then + begin + Result := graphicIndex; + break; + end; end; -function TX2GraphicContainer.GraphicByName(const AName: String): TX2GraphicCollectionItem; +function TX2GraphicContainer.GraphicByName(const AName: String): TX2GraphicContainerItem; +var + graphicIndex: Integer; + begin - Result := FGraphics.GraphicByName(AName); + Result := nil; + graphicIndex := IndexByName(AName); + if graphicIndex > -1 then + Result := Graphics[graphicIndex]; end; function TX2GraphicContainer.PictureByName(const AName: String): TPicture; +var + graphic: TX2GraphicContainerItem; + begin - Result := FGraphics.PictureByName(AName); + Result := nil; + graphic := GraphicByName(AName); + if Assigned(graphic) then + Result := graphic.Picture; end; procedure TX2GraphicContainer.AssignTo(Dest: TPersistent); +var + destContainer: TX2GraphicContainer; + graphicIndex: Integer; + begin if Dest is TX2GraphicContainer then - with TX2GraphicContainer(Dest) do - Graphics := Self.Graphics + begin + destContainer := TX2GraphicContainer(Dest); + destContainer.Clear(); + + for graphicIndex := 0 to Pred(Self.GraphicCount) do + with TX2GraphicContainerItem.Create(destContainer) do + begin + Assign(Self.Graphics[graphicIndex]); + Container := destContainer; + end; + end else inherited; end; -procedure TX2GraphicContainer.Notification(AComponent: TComponent; Operation: TOperation); +procedure TX2GraphicContainer.Clear(); begin - if not Assigned(FLists) then - exit; - - if Operation = opRemove then - FLists.Remove(AComponent) - else - // In design-time, if a TX2GraphicList is added and it doesn't yet have - // a container, assign ourselves to it for lazy programmers (such as me :)) - if (Operation = opInsert) and (csDesigning in ComponentState) and - (AComponent is TX2GraphicList) and - (not Assigned(TX2GraphicList(AComponent).Container)) then - TX2GraphicList(AComponent).Container := Self; - - inherited; + while GraphicsList.Count > 0 do + TX2GraphicContainerItem(GraphicsList.Last).Free(); end; -procedure TX2GraphicContainer.Notify(Item: TCollectionItem; - Action: TCollectionNotification); + +procedure TX2GraphicContainer.GetChildren(Proc: TGetChildProc; Root: TComponent); var - iList: Integer; + graphicIndex: Integer; + graphic: TX2GraphicContainerItem; begin - case Action of - cnAdded: - for iList := FLists.Count - 1 downto 0 do - TX2GraphicList(FLists[iList]).AddImage(Item.Index); - cnDeleting: - for iList := FLists.Count - 1 downto 0 do - TX2GraphicList(FLists[iList]).DeleteImage(Item.Index); + for graphicIndex := 0 to Pred(GraphicCount) do + begin + graphic := Graphics[graphicIndex]; + Proc(graphic); end; end; -procedure TX2GraphicContainer.Update(Item: TCollectionItem); +procedure TX2GraphicContainer.SetChildOrder(Component: TComponent; Order: Integer); +begin + if GraphicsList.IndexOf(Component) >= 0 then + (Component as TX2GraphicContainerItem).Index := Order; +end; + + +procedure TX2GraphicContainer.SetName(const NewName: TComponentName); var - iList: Integer; + oldName: String; + graphicIndex: Integer; begin - if Assigned(Item) then - for iList := FLists.Count - 1 downto 0 do - TX2GraphicList(FLists[iList]).UpdateImage(Item.Index) - else - for iList := FLists.Count - 1 downto 0 do - TX2GraphicList(FLists[iList]).RebuildImages(); + oldName := Self.Name; + + inherited; + + if Self.Name <> oldName then + begin + { Re-generate names for graphic components } + for graphicIndex := 0 to Pred(GraphicCount) do + Graphics[graphicIndex].Name := Graphics[graphicIndex].GenerateName(); + end; +end; + + +procedure TX2GraphicContainer.Notification(AComponent: TComponent; Operation: TOperation); +begin + inherited; + + case Operation of + opInsert: + { In design-time, if a TX2GraphicList is added and it doesn't yet have + a container, assign ourselves to it for lazy programmers (such as me :)) } + if (csDesigning in ComponentState) and + (AComponent is TX2GraphicList) and + (not Assigned(TX2GraphicList(AComponent).Container)) then + TX2GraphicList(AComponent).Container := Self; + + opRemove: + begin + if AComponent is TX2GraphicContainerItem then + RemoveGraphic(TX2GraphicContainerItem(AComponent)) + + else if AComponent is TX2GraphicList then + Lists.Remove(AComponent); + end; + end; +end; + + +procedure TX2GraphicContainer.DefineProperties(Filer: TFiler); +begin + inherited; + + { Previous versions used a Collection to hold the container items. As this + wasn't Visual Inheritance-friendly, container items are now TComponents. + This will convert the deprecated Graphics property. } + Filer.DefineProperty('Graphics', ConvertGraphics, nil, False); +end; + + +procedure TX2GraphicContainer.ConvertGraphics(Reader: TReader); +var + graphics: TCollection; + graphicIndex: Integer; + graphicItem: TDeprecatedGraphicItem; + +begin + graphics := TCollection.Create(TDeprecatedGraphicItem); + try + if Reader.NextValue = vaCollection then + begin + FConversionRequired := True; + Clear; + + Reader.ReadValue; + Reader.ReadCollection(graphics); + + for graphicIndex := 0 to Pred(graphics.Count) do + begin + graphicItem := TDeprecatedGraphicItem(graphics.Items[graphicIndex]); + + { Note: this create the item just fine, but won't add a line to the + form's definition; the designer can take care of that. } + with TX2GraphicContainerItem.Create(Self) do + begin + Picture := graphicItem.Picture; + PictureName := graphicItem.Name; + Container := Self; + end; + end; + end; + finally + FreeAndNil(graphics); + end; +end; + + +procedure TX2GraphicContainer.AddGraphic(const AGraphic: TX2GraphicContainerItem); +var + graphicIndex: Integer; + listIndex: Integer; + +begin + graphicIndex := GraphicsList.Add(AGraphic); + AGraphic.InternalSetContainer(Self); + AGraphic.FreeNotification(Self); + + for listIndex := Pred(Lists.Count) downto 0 do + TX2GraphicList(Lists[listIndex]).AddImage(graphicIndex); +end; + +procedure TX2GraphicContainer.RemoveGraphic(const AGraphic: TX2GraphicContainerItem); +var + graphicIndex: Integer; + listIndex: Integer; + +begin + graphicIndex := AGraphic.Index; + + if graphicIndex > -1 then + begin + for listIndex := Pred(Lists.Count) downto 0 do + TX2GraphicList(Lists[listIndex]).DeleteImage(graphicIndex); + + GraphicsList.Delete(graphicIndex); + AGraphic.InternalSetContainer(nil); + end; +end; + +procedure TX2GraphicContainer.UpdateGraphic(const AGraphic: TX2GraphicContainerItem); +var + graphicIndex: Integer; + listIndex: Integer; + +begin + graphicIndex := AGraphic.Index; + + if graphicIndex > -1 then + begin + for listIndex := Pred(Lists.Count) downto 0 do + TX2GraphicList(Lists[listIndex]).UpdateImage(graphicIndex); + end; end; procedure TX2GraphicContainer.RegisterList(const AList: TX2GraphicList); begin - if FLists.IndexOf(AList) = -1 then - FLists.Add(AList); + if Lists.IndexOf(AList) = -1 then + begin + Lists.Add(AList); + AList.FreeNotification(Self); + end; end; procedure TX2GraphicContainer.UnregisterList(const AList: TX2GraphicList); begin - FLists.Remove(AList); + if Lists.Remove(AList) > -1 then + AList.RemoveFreeNotification(Self); end; -procedure TX2GraphicContainer.SetGraphics(const Value: TX2GraphicCollection); + +function TX2GraphicContainer.GetGraphicCount(): Integer; begin - FGraphics.Assign(Value); + Result := GraphicsList.Count; +end; + +function TX2GraphicContainer.GetGraphics(Index: Integer): TX2GraphicContainerItem; +begin + Result := TX2GraphicContainerItem(GraphicsList[Index]); +end; + +procedure TX2GraphicContainer.SetGraphics(Index: Integer; const Value: TX2GraphicContainerItem); +begin + TX2GraphicContainerItem(GraphicsList[Index]).Assign(Value); end; @@ -600,7 +850,7 @@ begin if not Assigned(FContainer) then exit; - if (AIndex < 0) or (AIndex >= FContainer.Graphics.Count) then + if (AIndex < 0) or (AIndex >= FContainer.GraphicCount) then exit; if (not Assigned(FContainer.Graphics[AIndex].Picture.Graphic)) or @@ -669,8 +919,8 @@ begin end; -procedure TX2GraphicList.CreateImage(const AIndex: Integer; - var AImage, AMask: TBitmap); +procedure TX2GraphicList.BuildImage(const AIndex: Integer; + const AImage, AMask: TBitmap); function RGBTriple(const AColor: TColor): TRGBTriple; var cColor: Cardinal; @@ -707,13 +957,11 @@ var begin if not FConvert then begin - AImage := TBitmap.Create(); AImage.Width := Self.Width; AImage.Height := Self.Height; AImage.Canvas.Brush.Color := clWhite; AImage.Canvas.FillRect(Rect(0, 0, AImage.Width, AImage.Height)); - AMask := TBitmap.Create(); AMask.Assign(AImage); exit; end; @@ -826,7 +1074,7 @@ begin bmpImage := TBitmap.Create(); bmpMask := TBitmap.Create(); try - CreateImage(AIndex, bmpImage, bmpMask); + BuildImage(AIndex, bmpImage, bmpMask); Assert(AIndex <= Self.Count, 'AAAH! Images out of sync! *panics*'); if AIndex = Self.Count then @@ -859,7 +1107,7 @@ begin bmpImage := TBitmap.Create(); bmpMask := TBitmap.Create(); try - CreateImage(AIndex, bmpImage, bmpMask); + BuildImage(AIndex, bmpImage, bmpMask); Replace(AIndex, bmpImage, bmpMask); finally FreeAndNil(bmpMask); @@ -897,7 +1145,7 @@ begin if not Assigned(FContainer) then exit; - for iIndex := 0 to FContainer.Graphics.Count - 1 do + for iIndex := 0 to Pred(FContainer.GraphicCount) do AddImage(iIndex); finally EndUpdate(); @@ -998,7 +1246,30 @@ begin Dec(FUpdateCount); end; + + +{ TDeprecatedGraphicItem } +constructor TDeprecatedGraphicItem.Create(Collection: TCollection); +begin + inherited; + + FPicture := TPicture.Create(); +end; + +destructor TDeprecatedGraphicItem.Destroy(); +begin + FreeAndNil(FPicture); + + inherited; +end; + +procedure TDeprecatedGraphicItem.SetPicture(const Value: TPicture); +begin + FPicture.Assign(Value); +end; + + +initialization + RegisterClass(TX2GraphicContainerItem); + end. - - - diff --git a/Test/Forms/FMainGL.pas b/Test/Forms/FMainGL.pas index 9fe4aad..bc3c224 100644 --- a/Test/Forms/FMainGL.pas +++ b/Test/Forms/FMainGL.pas @@ -11,7 +11,6 @@ uses Menus, PNGImage, ToolWin, - IconXP, X2CLGraphicList; type