Fixed: memory leak in CreateImage method

Changed: GraphicList now uses TComponent-based items to support Visual Inheritance
This commit is contained in:
Mark van Renswoude 2007-01-04 19:47:47 +00:00
parent 7ca9314af1
commit a60c185db1
6 changed files with 895 additions and 387 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -11,7 +11,6 @@ uses
Menus,
PNGImage,
ToolWin,
IconXP,
X2CLGraphicList;
type