From 77e81e6501aeda84cc2d28d51ca9798226caaa4e Mon Sep 17 00:00:00 2001 From: ask Date: Sun, 10 Jul 2011 02:01:00 +0000 Subject: [PATCH] TAChart: Convert TChartListBox code to standard formatting git-svn-id: trunk@31632 - --- components/tachart/tachartlistbox.pas | 295 +++++++++++++------------- 1 file changed, 152 insertions(+), 143 deletions(-) diff --git a/components/tachart/tachartlistbox.pas b/components/tachart/tachartlistbox.pas index c8305dc0a8..d41dfe9432 100644 --- a/components/tachart/tachartlistbox.pas +++ b/components/tachart/tachartlistbox.pas @@ -24,7 +24,7 @@ Usage: - Add the ChartListbox to a form with a TChart - Connect the chart to the listbox by setting the chart property of the TChartlistbox. The ChartListbox will be populated with the series in the - chart und will automatically track changes of the series. + chart and will automatically track changes of the series. - Check/uncheck series in the ChartListbox to show/hide them in the chart. As usual, checking is done by mouse clicks or by pressing the space bar. - Play with the properties to modify the standard behavior, e.g. set @@ -43,78 +43,82 @@ uses TAChartUtils, TACustomSeries, TALegend, TAGraph; type - TChartListboxIndexEvent = procedure(Sender:TObject; Index:integer) of object; + TChartListboxIndexEvent = procedure ( + Sender: TObject; Index: Integer) of object; TCheckBoxesStyle = (cbsCheckbox, cbsRadiobutton); TChartListbox = class(TCustomListbox) private - FChart : TChart; - FListener : TListener; - FLegendItems : TChartLegendItems; - FShowSeriesIcons : boolean; - FShowCheckboxes : boolean; - FCheckStyle : TCheckBoxesStyle; - FLockCount : integer; - FSeriesIconClicked : integer; - FOnCheckboxClick : TChartListboxIndexEvent; - FOnSeriesIconClick : TChartListboxIndexEvent; - FOnItemClick : TChartListboxIndexEvent; - FOnPopulate : TNotifyEvent; - function GetChecked(AIndex:integer) : boolean; - function GetLegendItem(AIndex:integer) : TLegendItem; - function GetSeries(AIndex:integer) : TCustomChartSeries; - function GetSeriesCount : integer; - procedure SeriesChanged(ASender:TObject); - procedure SetChart(AValue:TChart); - procedure SetChecked(AIndex:integer; AValue:boolean); - procedure SetCheckStyle(AValue:TCheckBoxesStyle); - procedure SetShowCheckboxes(AValue:boolean); - procedure SetShowSeriesIcons(AValue:boolean); + FChart: TChart; + FListener: TListener; + FLegendItems: TChartLegendItems; + FShowSeriesIcons: Boolean; + FShowCheckboxes: Boolean; + FCheckStyle: TCheckBoxesStyle; + FLockCount: Integer; + FSeriesIconClicked: Integer; + FOnCheckboxClick: TChartListboxIndexEvent; + FOnSeriesIconClick: TChartListboxIndexEvent; + FOnItemClick: TChartListboxIndexEvent; + FOnPopulate: TNotifyEvent; + function GetChecked(AIndex: Integer): Boolean; + function GetLegendItem(AIndex: Integer): TLegendItem; + function GetSeries(AIndex: Integer): TCustomChartSeries; + function GetSeriesCount: Integer; + procedure SeriesChanged(ASender: TObject); + procedure SetChart(AValue: TChart); + procedure SetChecked(AIndex: Integer; AValue: Boolean); + procedure SetCheckStyle(AValue: TCheckBoxesStyle); + procedure SetShowCheckboxes(AValue: Boolean); + procedure SetShowSeriesIcons(AValue: Boolean); protected - procedure CalcRects(const AItemRect:TRect; out CheckboxRect,SeriesIconRect: TRect); - procedure ClickedCheckbox(AIndex:integer); virtual; - procedure ClickedItem(AIndex:integer); virtual; - procedure ClickedSeriesIcon(AIndex:integer); virtual; - function CreateLegendItems : TChartLegendItems; + procedure CalcRects( + const AItemRect: TRect; out CheckboxRect, SeriesIconRect: TRect); + procedure ClickedCheckbox(AIndex: Integer); virtual; + procedure ClickedItem(AIndex: Integer); virtual; + procedure ClickedSeriesIcon(AIndex: Integer); virtual; + function CreateLegendItems: TChartLegendItems; procedure DblClick; override; - procedure DrawItem(Index: Integer; ARect: TRect; AState: TOwnerDrawState); override; - function FirstCheckedIndex : integer; - function IsLocked : boolean; + procedure DrawItem( + Index: Integer; ARect: TRect; AState: TOwnerDrawState); override; + function FirstCheckedIndex: Integer; + function IsLocked: Boolean; procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure Lock; - procedure MouseDown(AButton: TMouseButton; AShift: TShiftState; AX, AY: Integer); override; - procedure Notification(AComponent: TComponent; AOperation: TOperation); override; + procedure MouseDown( + AButton: TMouseButton; AShift: TShiftState; AX, AY: Integer); override; + procedure Notification( + AComponent: TComponent; AOperation: TOperation); override; procedure Populate; procedure Unlock; public - constructor Create(AOwner:TComponent); override; + constructor Create(AOwner: TComponent); override; destructor Destroy; override; - function FindSeriesIndex(ASeries:TCustomChartSeries) : integer; + function FindSeriesIndex(ASeries: TCustomChartSeries): Integer; procedure MeasureItem(Index: Integer; var AHeight: Integer); override; - procedure RemoveSeries(ASeries:TCustomChartSeries); - property Checked[AIndex:integer] : boolean read GetChecked write SetChecked; - property Series[AIndex:integer] : TCustomChartSeries read GetSeries; - property SeriesCount : integer read GetSeriesCount; + procedure RemoveSeries(ASeries: TCustomChartSeries); + property Checked[AIndex: Integer]: Boolean read GetChecked write SetChecked; + property Series[AIndex: Integer]: TCustomChartSeries read GetSeries; + property SeriesCount: Integer read GetSeriesCount; published - property Chart : TChart - read FChart write SetChart; - property CheckStyle : TCheckBoxesStyle + property Chart: TChart read FChart write SetChart; + property CheckStyle: TCheckBoxesStyle read FCheckStyle write SetCheckStyle default cbsCheckbox; - property ShowCheckboxes : boolean + property ShowCheckboxes: Boolean read FShowCheckboxes write SetShowCheckboxes default true; - property ShowSeriesIcons : boolean + property ShowSeriesIcons: Boolean read FShowSeriesIcons write SetShowSeriesIcons default true; - property OnCheckboxClick : TChartListboxIndexEvent + property OnCheckboxClick: TChartListboxIndexEvent read FOnCheckboxClick write FOnCheckboxClick; - property OnItemClick : TChartListboxIndexEvent + property OnItemClick: TChartListboxIndexEvent read FOnItemClick write FOnItemClick; - property OnSeriesIconClick : TChartListboxIndexEvent + property OnSeriesIconClick: TChartListboxIndexEvent read FOnSeriesIconClick write FOnSeriesIconClick; - property OnPopulate : TNotifyEvent + property OnPopulate: TNotifyEvent read FOnPopulate write FOnPopulate; property Align; @@ -181,14 +185,14 @@ procedure Register; implementation uses - math, LCLIntf, Themes, TAGeometry, TADrawUtils, TADrawerCanvas; + Math, LCLIntf, Themes, TAGeometry, TADrawUtils, TADrawerCanvas; procedure Register; begin RegisterComponents(CHART_COMPONENT_IDE_PAGE, [TChartListbox]); end; -constructor TChartListbox.Create(AOwner:TComponent); +constructor TChartListbox.Create(AOwner: TComponent); begin inherited Create(AOwner); Style := lbOwnerDrawFixed; @@ -204,63 +208,65 @@ begin inherited Destroy; end; -procedure TChartListbox.CalcRects(const AItemRect:TRect; - out CheckboxRect,SeriesIconRect: TRect); +procedure TChartListbox.CalcRects( + const AItemRect: TRect; out CheckboxRect, SeriesIconRect: TRect); { based on the rect of a listbox item, calculates the locations of the checkbox and of the series icon } var - w, x: integer; + w, x: Integer; begin CheckBoxRect := Rect(-1, -1, -1, -1); SeriesIconRect := Rect(-1, -1, -1, -1); w := GetSystemMetrics(SM_CYMENUCHECK); x := 2; if FShowCheckboxes then begin - CheckboxRect := Bounds(AItemRect.Left+1, AItemRect.Top+1, w, w); + CheckboxRect := Bounds(AItemRect.Left + 1, AItemRect.Top + 1, w, w); if FShowSeriesIcons then inc(x, CheckboxRect.Right); - end else begin + end + else begin if FShowSeriesIcons then inc(x, AItemRect.Left); end; if FShowSeriesIcons then - SeriesIconRect := Rect(x, AItemRect.Top+2, x+FChart.Legend.SymbolWidth, AItemRect.Bottom-2); + SeriesIconRect := Rect( + x, AItemRect.Top + 2, x + FChart.Legend.SymbolWidth, AItemRect.Bottom - 2); end; -procedure TChartListbox.ClickedCheckbox(AIndex:integer); +procedure TChartListbox.ClickedCheckbox(AIndex: Integer); begin Checked[AIndex] := not Checked[AIndex]; if Assigned(OnCheckboxClick) then - OnCheckboxClick(self, AIndex); + OnCheckboxClick(Self, AIndex); end; -procedure TChartListbox.ClickedItem(AIndex:integer); +procedure TChartListbox.ClickedItem(AIndex: Integer); begin if Assigned(OnItemClick) then - OnItemClick(self, AIndex); + OnItemClick(Self, AIndex); end; -procedure TChartListbox.ClickedSeriesIcon(AIndex:integer); +procedure TChartListbox.ClickedSeriesIcon(AIndex: Integer); begin if Assigned(OnSeriesIconClick) then - OnSeriesIconClick(self, AIndex); + OnSeriesIconClick(Self, AIndex); end; -function TChartListbox.CreateLegendItems : TChartLegendItems; +function TChartListbox.CreateLegendItems: TChartLegendItems; { creates the a TLegendItems list and populates it with information for all series contained in the Chart. In case of MultiLegend items, only a single legend item is used } var - i : integer; - j : integer = MaxInt; + i: Integer; + j: Integer = MaxInt; begin - result := TChartLegendItems.Create; + Result := TChartLegendItems.Create; try if FChart <> nil then - for i:=0 to FChart.SeriesCount-1 do begin - if (FChart.Series[i] is TCustomChartSeries) then begin - TCustomChartSeries(FChart.Series[i]).GetSingleLegendItem(result); - result[i].Owner := FChart.Series[i]; + for i := 0 to FChart.SeriesCount - 1 do begin + if FChart.Series[i] is TCustomChartSeries then begin + TCustomChartSeries(FChart.Series[i]).GetSingleLegendItem(Result); + Result[i].Owner := FChart.Series[i]; end; end; for i := Result.Count - 1 downto 0 do @@ -277,30 +283,29 @@ end; procedure TChartListbox.DblClick; begin inherited DblClick; - if (FSeriesIconClicked <> -1) then + if FSeriesIconClicked <> -1 then ClickedSeriesIcon(FSeriesIconClicked); end; -procedure TChartListbox.DrawItem(Index: Integer; ARect: TRect; - AState: TOwnerDrawState); +procedure TChartListbox.DrawItem( + Index: Integer; ARect: TRect; AState: TOwnerDrawState); { draws the listbox item } const - IsChecked : array[TCheckboxesStyle, Boolean] of integer = ( + IS_CHECKED: array[TCheckboxesStyle, Boolean] of Integer = ( (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED), (DFCS_BUTTONRADIO, DFCS_BUTTONRADIO or DFCS_CHECKED) ); var - id : IChartDrawer; - Rcb, Ricon: TRect; - te : TThemedElementDetails; - x : integer; + id: IChartDrawer; + rcb, ricon: TRect; + te: TThemedElementDetails; + x: Integer; begin Unused(AState); - if FChart = nil then - exit; + if FChart = nil then exit; - CalcRects(ARect, Rcb, Ricon); + CalcRects(ARect, rcb, ricon); if FShowCheckboxes then begin if ThemeServices.ThemesEnabled then begin @@ -316,98 +321,102 @@ begin else te := ThemeServices.GetElementDetails(tbRadioButtonUnCheckedNormal); end; - ThemeServices.DrawElement(Canvas.Handle, te, Rcb); - end else - DrawFrameControl(Canvas.Handle, Rcb, DFC_BUTTON, IsChecked[FCheckStyle, Checked[Index]]); - x := Rcb.Right; - end else + ThemeServices.DrawElement(Canvas.Handle, te, rcb); + end + else + DrawFrameControl( + Canvas.Handle, rcb, DFC_BUTTON, IS_CHECKED[FCheckStyle, Checked[Index]]); + x := rcb.Right; + end + else x := ARect.Left; if FShowSeriesIcons then begin id := TCanvasDrawer.Create(Canvas); id.Pen := Chart.Legend.SymbolFrame; - FLegendItems[Index].Draw(id, Ricon); + FLegendItems[Index].Draw(id, ricon); end else - Canvas.TextOut(x+2, ARect.Top, FLegendItems.Items[Index].Text); + Canvas.TextOut(x + 2, ARect.Top, FLegendItems.Items[Index].Text); end; -function TChartListbox.FindSeriesIndex(ASeries:TCustomChartSeries) : integer; +function TChartListbox.FindSeriesIndex(ASeries: TCustomChartSeries): Integer; { searches the internal legend items list for the specified series } var - i : integer; - ser : TBasicChartSeries; + i: Integer; + ser: TBasicChartSeries; begin - for i:=0 to FLegendItems.Count-1 do begin + for i := 0 to FLegendItems.Count - 1 do begin ser := GetSeries(i); if ser = ASeries then begin - result := i; + Result := i; exit; end; end; - result := -1; + Result := -1; end; -function TChartListbox.FirstCheckedIndex : integer; +function TChartListbox.FirstCheckedIndex: Integer; { Returns the index of the first listbox series that is active } var - i : integer; + i: Integer; begin - for i:=0 to FLegendItems.Count-1 do + for i := 0 to FLegendItems.Count - 1 do if Checked[i] then begin - result := i; + Result := i; exit; end; - result := -1; + Result := -1; end; -function TChartListbox.GetChecked(AIndex:integer) : boolean; +function TChartListbox.GetChecked(AIndex: Integer): Boolean; { report the checked status. This is determined by the visibility of the series with the given index. } var - ser : TBasicChartSeries; + ser: TBasicChartSeries; begin ser := GetSeries(AIndex); - result := ser.Active; + Result := ser.Active; end; -function TChartListbox.GetLegendItem(AIndex:integer) : TLegendItem; +function TChartListbox.GetLegendItem(AIndex: Integer): TLegendItem; begin - result := FLegendItems[AIndex]; + Result := FLegendItems[AIndex]; end; -function TChartListbox.GetSeries(AIndex:integer) : TCustomChartSeries; +function TChartListbox.GetSeries(AIndex: Integer): TCustomChartSeries; { extracts, for the given index, the series from the internal legend items list. } var - legitem : TLegendItem; + legitem: TLegendItem; begin legitem := GetLegendItem(AIndex); if (legitem <> nil) and (legitem.Owner is TCustomChartSeries) then - result := TCustomChartSeries(legitem.Owner) + Result := TCustomChartSeries(legitem.Owner) else - result := nil; + Result := nil; end; -function TChartListbox.GetSeriesCount : integer; +function TChartListbox.GetSeriesCount : Integer; { determines the number of series displayed in the listbox. Note that this may be different from the Chart.SeriesCount if RemoveSeries has been called } begin - result := FLegendItems.Count; + Result := FLegendItems.Count; end; -function TChartListbox.IsLocked : boolean; +function TChartListbox.IsLocked : Boolean; begin - result := FLockCount <> 0; + Result := FLockCount <> 0; end; procedure TChartListBox.KeyDown(var Key: Word; Shift: TShiftState); { allows checking/unchecking of items by means of pressing the space bar } begin - if (Key = VK_SPACE) and (Shift=[]) and FShowCheckboxes then begin + if (Key = VK_SPACE) and (Shift = []) and FShowCheckboxes then begin ClickedCheckbox(ItemIndex); Key := VK_UNKNOWN; - end else + end + else inherited KeyDown(Key,Shift); end; @@ -428,8 +437,8 @@ begin AHeight := Max(AHeight, GetSystemMetrics(SM_CYMENUCHECK) + 2); end; -procedure TChartListbox.MouseDown(AButton: TMouseButton; AShift: TShiftState; - AX, AY: Integer); +procedure TChartListbox.MouseDown( + AButton: TMouseButton; AShift: TShiftState; AX, AY: Integer); { standard MouseDown handler: checks if the click occured on the checkbox, on the series icon, or on the text. The visibility state of the item's series is changed when clicking on the @@ -440,22 +449,22 @@ procedure TChartListbox.MouseDown(AButton: TMouseButton; AShift: TShiftState; checkbox nor the series icon. } var - Rcb, Ricon : TRect; - index : integer; - P : TPoint; - done : boolean; + rcb, ricon: TRect; + index: Integer; + p: TPoint; + done: Boolean; begin - if (AButton = mbLeft) then begin - P := Point(AX, AY); + if AButton = mbLeft then begin + p := Point(AX, AY); index := GetIndexAtXY(AX, AY); - CalcRects(ItemRect(index), Rcb, Ricon); + CalcRects(ItemRect(index), rcb, ricon); FSeriesIconClicked := -1; done := false; - if FShowCheckboxes and IsPointInRect(P, Rcb) then begin + if FShowCheckboxes and IsPointInRect(p, rcb) then begin ClickedCheckbox(index); done := true; end; - if FShowSeriesIcons and PtInRect(Ricon, P) then begin + if FShowSeriesIcons and PtInRect(ricon, p) then begin FSeriesIconClicked := index; // remember the clicked index for the double click event done := true; @@ -466,8 +475,8 @@ begin inherited MouseDown(AButton, AShift, AX, AY); end; -procedure TChartListbox.Notification(AComponent: TComponent; - AOperation: TOperation); +procedure TChartListbox.Notification( + AComponent: TComponent; AOperation: TOperation); { avoids AV if Chart is deleted from its container form } begin if (AOperation = opRemove) and (AComponent = FChart) then @@ -479,7 +488,7 @@ procedure TChartListbox.Populate; { populates the listbox with all series contained in the chart. Use the event OnPopulate if you don't omit special series from the listbox (RemoveSeries) } var - i : integer; + i: Integer; begin try Items.BeginUpdate; @@ -487,7 +496,7 @@ begin if FChart <> nil then begin FreeAndNil(FLegendItems); FLegendItems := CreateLegendItems; - for i:=0 to FLegendItems.Count-1 do + for i := 0 to FLegendItems.Count - 1 do Items.Add(''); // the caption is owner-drawn using info from the FLegendItems // --> no need to pass the text here @@ -500,10 +509,10 @@ begin end; end; -procedure TChartListbox.RemoveSeries(ASeries:TCustomChartSeries); +procedure TChartListbox.RemoveSeries(ASeries: TCustomChartSeries); { removes the series from the listbox, but keeps it in the chart } var - index : integer; + index: Integer; begin index := FindSeriesIndex(ASeries); if index <> -1 then begin @@ -513,11 +522,11 @@ begin end; end; -procedure TChartListbox.SeriesChanged(ASender:TObject); +procedure TChartListbox.SeriesChanged(ASender: TObject); { Notification procedure of the listener. Responds to chart broadcasts by populating the listbox with the chart's series } var - index : integer; + index: Integer; begin if not IsLocked then begin Populate; @@ -526,13 +535,13 @@ begin if (FCheckStyle = cbsRadioButton) and (ASender is TBasicChartSeries) then begin index := FindSeriesIndex(ASender as TCustomChartSeries); - if (index <> -1) then + if index <> -1 then Checked[index] := (ASender as TCustomChartSeries).Active; end; end; end; -procedure TChartListbox.SetChart(AValue:TChart); +procedure TChartListbox.SetChart(AValue: TChart); { connects the ListBox to the chart } begin if FChart = AValue then exit; @@ -545,12 +554,12 @@ begin SeriesChanged(nil); end; -procedure TChartListbox.SetChecked(AIndex:integer; AValue:boolean); +procedure TChartListbox.SetChecked(AIndex: Integer; AValue: Boolean); { shows/hides the series with the specified index of its listbox item. In case of radiobutton style, all other series are hidden if AValue=true } var - ser : TBasicChartSeries; - i : integer; + ser: TBasicChartSeries; + i: Integer; begin ser := GetSeries(AIndex); if ser <> nil then begin @@ -570,11 +579,11 @@ begin end; end; -procedure TChartlistbox.SetCheckStyle(AValue:TCheckBoxesStyle); +procedure TChartlistbox.SetCheckStyle(AValue: TCheckBoxesStyle); { selects "checkbox" or "radiobutton" styles. In radiobutton mode, only one series can be visible } var - j : integer; + j: Integer; begin if AValue <> FCheckStyle then begin if AValue = cbsRadioButton then @@ -588,7 +597,7 @@ begin end; end; -procedure TChartListbox.SetShowCheckboxes(AValue:boolean); +procedure TChartListbox.SetShowCheckboxes(AValue: Boolean); begin if AValue <> FShowCheckboxes then begin FShowCheckboxes := AValue; @@ -596,7 +605,7 @@ begin end; end; -procedure TChartListbox.SetShowSeriesIcons(AValue:boolean); +procedure TChartListbox.SetShowSeriesIcons(AValue: Boolean); begin if AValue <> FShowSeriesIcons then begin FShowSeriesIcons := AValue;