TAChart series editor: adding, deleting and selection of series

issue #13214 part 3

git-svn-id: trunk@18775 -
This commit is contained in:
ask 2009-02-20 14:22:48 +00:00
parent 7ab4967ab9
commit ee315fb844
5 changed files with 223 additions and 16 deletions

View File

@ -198,6 +198,8 @@ type
property Title: String read FTitle write FTitle;
end;
TSeriesClass = class of TBasicChartSeries;
{ TChartSeriesList }
TChartSeriesList = class(TPersistent)
@ -412,16 +414,26 @@ type
end;
procedure Register;
procedure RegisterSeriesClass(ASeriesClass: TSeriesClass; const ACaption: string);
var
SeriesClassRegistry: TStringList;
implementation
uses
Clipbrd, Math;
Clipbrd, LCLProc, Math;
const
MinDouble = -1.7e308;
MaxDouble = 1.7e308;
procedure RegisterSeriesClass(ASeriesClass: TSeriesClass; const ACaption: string);
begin
if SeriesClassRegistry.IndexOfObject(TObject(ASeriesClass)) < 0 then
SeriesClassRegistry.AddObject(ACaption, TObject(ASeriesClass));
end;
{ TChartPen }
procedure TChartPen.SetVisible(Value: Boolean);
@ -1836,8 +1848,10 @@ end;
procedure TBasicChartSeries.ReadState(Reader: TReader);
begin
inherited ReadState(Reader);
if Reader.Parent is TChart then
(AParent as TChart).AddSeries(Self);
if Reader.Parent is TChart then begin
(Reader.Parent as TChart).AddSeries(Self);
//DebugLn('TAChart %s: %d series', [Reader.Parent.Name, (Reader.Parent as TChart).SeriesCount]);
end;
end;
procedure TBasicChartSeries.SetParentComponent(AParent: TComponent);
@ -1847,8 +1861,16 @@ begin
end;
procedure Register;
var
i: Integer;
sc: TSeriesClass;
begin
RegisterComponents('Additional', [TChart]);
for i := 0 to SeriesClassRegistry.Count - 1 do begin
sc := TSeriesClass(SeriesClassRegistry.Objects[i]);
RegisterClass(sc);
RegisterNoIcon([sc]);
end;
end;
{ TChartSeriesList }
@ -1884,10 +1906,14 @@ end;
procedure TChartSeriesList.SetItem(
AIndex: Integer; const AValue: TBasicChartSeries);
begin
FList.Items[AIndex] := AValue;
GetItem(AIndex).Assign(AValue);
end;
initialization
{$I tagraph.lrs}
SeriesClassRegistry := TStringList.Create;
finalization
SeriesClassRegistry.Free;
end.

View File

@ -1644,4 +1644,11 @@ begin
ACanvas.LineTo(ARect.Right, y);
end;
initialization
RegisterSeriesClass(TSerie, 'Line series');
RegisterSeriesClass(TAreaSeries, 'Area series');
RegisterSeriesClass(TBarSeries, 'Bar series');
RegisterSeriesClass(TPieSeries, 'Pie series');
RegisterSeriesClass(TLine, 'Line');
end.

View File

@ -15,6 +15,7 @@ object SeriesEditorForm: TSeriesEditorForm
Width = 325
Align = alClient
MultiSelect = True
OnClick = SeriesListBoxClick
TabOrder = 0
end
object MainMenu1: TMainMenu
@ -22,10 +23,10 @@ object SeriesEditorForm: TSeriesEditorForm
top = 132
object miAdd: TMenuItem
Caption = 'Add'
object miAddSeries: TMenuItem
Caption = 'Series'
OnClick = miAddSeriesClick
end
end
object miDelete: TMenuItem
Caption = 'Delete'
OnClick = miDeleteClick
end
end
end

View File

@ -6,8 +6,8 @@ LazarusResources.Add('TSeriesEditorForm','FORMDATA',[
+'ientHeight'#3'T'#1#11'ClientWidth'#3'E'#1#4'Menu'#7#9'MainMenu1'#7'OnClose'
+#7#9'FormClose'#9'OnDestroy'#7#11'FormDestroy'#10'LCLVersion'#6#6'0.9.27'#0#8
+'TListBox'#13'SeriesListBox'#6'Height'#3'T'#1#5'Width'#3'E'#1#5'Align'#7#8'a'
+'lClient'#11'MultiSelect'#9#8'TabOrder'#2#0#0#0#9'TMainMenu'#9'MainMenu1'#4
+'left'#2'<'#3'top'#3#132#0#0#9'TMenuItem'#5'miAdd'#7'Caption'#6#3'Add'#0#9'T'
+'MenuItem'#11'miAddSeries'#7'Caption'#6#6'Series'#7'OnClick'#7#16'miAddSerie'
+'sClick'#0#0#0#0#0
+'lClient'#11'MultiSelect'#9#7'OnClick'#7#18'SeriesListBoxClick'#8'TabOrder'#2
+#0#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#2'<'#3'top'#3#132#0#0#9'TMenuItem'#5
+'miAdd'#7'Caption'#6#3'Add'#0#0#9'TMenuItem'#8'miDelete'#7'Caption'#6#6'Dele'
+'te'#7'OnClick'#7#13'miDeleteClick'#0#0#0#0
]);

View File

@ -39,18 +39,30 @@ type
TSeriesEditorForm = class(TForm)
MainMenu1: TMainMenu;
miAddSeries: TMenuItem;
miDelete: TMenuItem;
miAdd: TMenuItem;
SeriesListBox: TListBox;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure miAddSeriesClick(Sender: TObject);
procedure miDeleteClick(Sender: TObject);
procedure SeriesListBoxClick(Sender: TObject);
private
FChart: TChart;
FComponentEditor: TSeriesComponentEditor;
FPropertyEditor: TSeriesPropertyEditor;
FDesigner: TComponentEditorDesigner;
procedure BuildCaption;
procedure InitAddMenu;
procedure RefreshSeriesList;
procedure miAddSeriesClick(Sender: TObject);
function FindSeries(ASeries: TObject; out AIndex: Integer): Boolean;
procedure SelectionChanged;
procedure OnComponentRenamed(AComponent: TComponent);
procedure OnPersistentDeleting(APersistent: TPersistent);
procedure OnGetSelection(const ASelection: TPersistentSelectionList);
procedure OnSetSelection(const ASelection: TPersistentSelectionList);
procedure OnPersistentAdded(APersistent: TPersistent; ASelect: Boolean);
public
constructor Create(
AOwner: TComponent; AChart: TChart; AComponentEditor: TComponentEditor;
@ -141,6 +153,11 @@ end;
{ TSeriesEditorForm }
procedure TSeriesEditorForm.BuildCaption;
begin
Caption := sesSeriesEditorTitle + ' - ' + FChart.Name;
end;
constructor TSeriesEditorForm.Create(
AOwner: TComponent; AChart: TChart; AComponentEditor: TComponentEditor;
APropertyEditor: TPropertyEditor);
@ -153,8 +170,28 @@ begin
FDesigner := FComponentEditor.Designer
else
FDesigner := FindRootDesigner(AChart) as TComponentEditorDesigner;
Caption := sesSeriesEditorTitle + ' - ' + FChart.Name;
BuildCaption;
InitAddMenu;
RefreshSeriesList;
GlobalDesignHook.AddHandlerComponentRenamed(@OnComponentRenamed);
GlobalDesignHook.AddHandlerPersistentDeleting(@OnPersistentDeleting);
GlobalDesignHook.AddHandlerGetSelection(@OnGetSelection);
GlobalDesignHook.AddHandlerSetSelection(@OnSetSelection);
GlobalDesignHook.AddHandlerPersistentAdded(@OnPersistentAdded);
SelectionChanged;
end;
function TSeriesEditorForm.FindSeries(
ASeries: TObject; out AIndex: Integer): Boolean;
begin
if ASeries is TBasicChartSeries then
AIndex := SeriesListBox.Items.IndexOfObject(ASeries)
else
AIndex := -1;
Result := AIndex >= 0;
end;
procedure TSeriesEditorForm.FormClose(Sender: TObject;
@ -165,14 +202,127 @@ end;
procedure TSeriesEditorForm.FormDestroy(Sender: TObject);
begin
if FComponentEditor <> nil then
if FComponentEditor <> nil then begin
FComponentEditor.FEditorForm := nil;
if
(FChart <> nil) and (not (csDestroying in FChart.ComponentState)) and
(SeriesListBox.SelCount > 0)
then
GlobalDesignHook.SelectOnlyThis(FChart);
end;
if FPropertyEditor <> nil then
FPropertyEditor.FEditorForm := nil;
if Assigned(GlobalDesignHook) then
GlobalDesignHook.RemoveAllHandlersForObject(Self);
end;
procedure TSeriesEditorForm.InitAddMenu;
var
i: Integer;
mi: TMenuItem;
begin
for i := 0 to SeriesClassRegistry.Count - 1 do begin
mi := TMenuItem.Create(Self);
mi.OnClick := @miAddSeriesClick;
mi.Caption := SeriesClassRegistry[i];
mi.Tag := i;
miAdd.Add(mi);
end;
end;
procedure TSeriesEditorForm.miAddSeriesClick(Sender: TObject);
var
s: TBasicChartSeries;
c: TSeriesClass;
n: String;
begin
c := TSeriesClass(SeriesClassRegistry.Objects[(Sender as TMenuItem).Tag]);
n := Copy(c.ClassName, 2, Length(c.ClassName) - 1);
s := c.Create(FChart.Owner);
try
s.Name := FDesigner.CreateUniqueComponentName(FChart.Name + n);
FChart.AddSeries(s);
FDesigner.PropertyEditorHook.PersistentAdded(s, true);
FDesigner.Modified;
RefreshSeriesList;
except
s.Free;
raise;
end;
end;
procedure TSeriesEditorForm.miDeleteClick(Sender: TObject);
var
i: Integer;
s: TBasicChartSeries;
begin
if SeriesListBox.SelCount = 0 then exit;
for i := SeriesListBox.Items.Count - 1 downto 0 do
if SeriesListBox.Selected[i] then begin
s := TBasicChartSeries(SeriesListBox.Items.Objects[i]);
SeriesListBox.Items.Delete(i);
FDesigner.PropertyEditorHook.PersistentDeleting(s);
s.Free;
end;
FDesigner.Modified;
SelectionChanged;
end;
procedure TSeriesEditorForm.OnComponentRenamed(AComponent: TComponent);
var
i: Integer;
begin
if AComponent = nil then exit;
if FindSeries(AComponent, i) then
SeriesListBox.Items[i] := AComponent.Name
else if AComponent = FChart then
BuildCaption;
end;
procedure TSeriesEditorForm.OnGetSelection(
const ASelection: TPersistentSelectionList);
var
i: Integer;
begin
if ASelection = nil then exit;
ASelection.Clear;
with SeriesListBox do
for i := 0 to Items.Count - 1 do
if Selected[i] then
ASelection.Add(TPersistent(Items.Objects[i]));
end;
procedure TSeriesEditorForm.OnPersistentAdded(
APersistent: TPersistent; ASelect: Boolean);
var
i: Integer;
s: TBasicChartSeries;
begin
if (APersistent = nil) or not (APersistent is TBasicChartSeries) then exit;
s := APersistent as TBasicChartSeries;
if s.ParentChart <> FChart then exit;
i := SeriesListBox.Items.AddObject(s.Name, s);
SeriesListBox.Selected[i] := ASelect;
end;
procedure TSeriesEditorForm.OnPersistentDeleting(APersistent: TPersistent);
var
i: Integer;
begin
if FindSeries(APersistent, i) then
SeriesListBox.Items.Delete(i);
end;
procedure TSeriesEditorForm.OnSetSelection(
const ASelection: TPersistentSelectionList);
var
i, j: Integer;
begin
if ASelection = nil then exit;
SeriesListBox.ClearSelection;
for i := 0 to ASelection.Count - 1 do
if FindSeries(ASelection.Items[i], j) then
SeriesListBox.Selected[j] := true;
end;
procedure TSeriesEditorForm.RefreshSeriesList;
@ -184,6 +334,29 @@ begin
SeriesListBox.Items.AddObject(FChart.Series[i].Name, FChart.Series[i]);
end;
procedure TSeriesEditorForm.SelectionChanged;
var
sel: TPersistentSelectionList;
begin
GlobalDesignHook.RemoveHandlerSetSelection(@OnSetSelection);
try
sel := TPersistentSelectionList.Create;
try
OnGetSelection(sel);
FDesigner.PropertyEditorHook.SetSelection(sel) ;
finally
sel.Free;
end;
finally
GlobalDesignHook.AddHandlerSetSelection(@OnSetSelection);
end;
end;
procedure TSeriesEditorForm.SeriesListBoxClick(Sender: TObject);
begin
SelectionChanged;
end;
initialization
{$I taserieseditor.lrs}