From 683b03a129ad16ba1ead2fa5eebaba3862d35a29 Mon Sep 17 00:00:00 2001 From: jesus Date: Thu, 12 Jul 2007 07:31:39 +0000 Subject: [PATCH] LCL, grids, improved dbgrid ownerdraw delphi compatibility, fixed dbgrid scroll issue (9219), improved and fixed dbgrid with native style git-svn-id: trunk@11468 - --- lcl/dbgrids.pas | 187 ++++++++++++++++++++++++++++++------------------ lcl/grids.pas | 70 +++++++++++++++--- 2 files changed, 180 insertions(+), 77 deletions(-) diff --git a/lcl/dbgrids.pas b/lcl/dbgrids.pas index 67f38c8557..42be125242 100644 --- a/lcl/dbgrids.pas +++ b/lcl/dbgrids.pas @@ -45,7 +45,7 @@ interface uses Classes, LCLIntf, LCLProc, Graphics, SysUtils, LCLType, stdctrls, DB, - LMessages, Grids, Dialogs, Controls; + LMessages, Grids, Dialogs, Controls, Themes; type TCustomDbGrid = class; @@ -109,7 +109,10 @@ type TDbGridSelEditorEvent = procedure(Sender: TObject; Column: TColumn; var Editor: TWinControl) of object; - + + TPrepareDbGridCanvasEvent = + procedure(sender: TObject; DataCol: Integer; + Column: TColumn; AState: TGridDrawState) of object; type @@ -312,6 +315,7 @@ type FCheckedBitmap, FUnCheckedBitmap, FGrayedBitmap: TBitmap; FNeedUpdateWidths: boolean; FSelectedRows: TBookmarkList; + FOnPrepareCanvas: TPrepareDbGridCanvasEvent; procedure EmptyGrid; procedure CheckWidths; function GetCurrentColumn: TColumn; @@ -380,11 +384,13 @@ type function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override; function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override; procedure DoOnChangeBounds; override; + procedure DoPrepareCanvas(aCol,aRow:Integer; aState: TGridDrawState); override; procedure DrawAllRows; override; procedure DrawFocusRect(aCol,aRow:Integer; ARect:TRect); override; procedure DrawRow(ARow: Integer); override; procedure DrawCell(aCol,aRow: Integer; aRect: TRect; aState:TGridDrawState); override; procedure DrawCheckboxBitmaps(aCol: Integer; aRect: TRect; F: TField); + procedure DrawFixedText(aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState); procedure EditingColumn(aCol: Integer; Ok: boolean); procedure EditorCancelEditing; procedure EditorDoGetValue; override; @@ -442,6 +448,7 @@ type property OnColumnSized: TNotifyEvent read FOnColumnSized write FOnColumnSized; property OnDrawColumnCell: TDrawColumnCellEvent read FOnDrawColumnCell write FOnDrawColumnCell; property OnFieldEditMask: TGetDbEditMaskEvent read FOnFieldEditMask write FOnFieldEditMask; + property OnPrepareCanvas: TPrepareDbGridCanvasEvent read FOnPrepareCanvas write FOnPrepareCanvas; property OnSelectEditor: TDbGridSelEditorEvent read FOnSelectEditor write FOnSelectEditor; property OnTitleClick: TDBGridClickEvent read FOnTitleClick write FOnTitleClick; property OnUserCheckboxBitmap: TUserCheckboxBitmapEvent read FOnUserCheckboxBitmap write FOnUserCheckboxBitmap; @@ -1692,31 +1699,16 @@ end; procedure TCustomDBGrid.DefaultDrawCell(aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState); - - function GetDatasetState: TDataSetState; - begin - if FDatalink.Active then - result := FDataLink.DataSet.State - else - result := dsInactive; - end; - + var S: string; F: TField; begin + if gdFixed in aState then begin - if (ACol=0) and FDrawingActiveRecord then begin - DrawIndicator(Canvas, aRect, GetDataSetState, FDrawingMultiSelRecord); - {$ifdef dbgGridPaint} - dbgOut('>'); - {$endif} - end else - if (ACol=0) and FDrawingMultiSelRecord then - DrawIndicator(Canvas, aRect, dsCurValue{dummy}, True) - else + if TitleStyle<>tsNative then - DrawColumnText(aCol, aRow, aRect, aState); + DrawFixedText(aCol, aRow, aRect, aState); end else if not FDrawingEmptyDataset then begin @@ -1757,6 +1749,18 @@ begin EndUpdate(False); end; +procedure TCustomDBGrid.DoPrepareCanvas(aCol, aRow: Integer; + aState: TGridDrawState); +var + DataCol: Integer; +begin + if (ARow>=FixedRows) and Assigned(OnPrepareCanvas) then begin + DataCol := ColumnIndexFromGridColumn(aCol); + if DataCol>=0 then + OnPrepareCanvas(Self, DataCol, TColumn(Columns[DataCol]), aState); + end; +end; + procedure TCustomDBGrid.BeforeMoveSelection(const DCol,DRow: Integer); begin if FSelectionLock then @@ -2399,7 +2403,7 @@ procedure TCustomDBGrid.DrawFocusRect(aCol, aRow: Integer; ARect: TRect); begin // Draw focused cell if we have the focus if Self.Focused and (dgAlwaysShowSelection in Options) and - FDatalink.Active then + FDatalink.Active and DefaultDrawing then begin CalcFocusRect(aRect); DrawRubberRect(Canvas, aRect, FocusColor); @@ -2430,30 +2434,53 @@ end; procedure TCustomDBGrid.DrawCell(aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState); +var + DataCol: Integer; begin PrepareCanvas(aCol, aRow, aState); - if DefaultDrawing then + + if (gdFixed in aState) or DefaultDrawing then Canvas.FillRect(aRect); + {$ifdef dbgGridPaint} DbgOut(' ',IntToStr(aCol)); if gdSelected in aState then DbgOut('S'); if gdFocused in aState then DbgOut('*'); if gdFixed in aState then DbgOut('F'); {$endif dbgGridPaint} - if Assigned(OnDrawColumnCell) and not(CsDesigning in ComponentState) then - OnDrawColumnCell(Self, aRect, aCol, TColumn(ColumnFromGridColumn(aCol)), aState) - else + + if (gdFixed in aState) or DefaultDrawing then DefaultDrawCell(aCol, aRow, aRect, aState); + + if (ARow>=FixedRows) and Assigned(OnDrawColumnCell) and + not (csDesigning in ComponentState) then begin + + DataCol := ColumnIndexFromGridColumn(aCol); + if DataCol>=0 then + OnDrawColumnCell(Self, aRect, DataCol, TColumn(Columns[DataCol]), aState); + end; + DrawCellGrid(aCol, aRow, aRect, aState); - if TitleStyle=tsNative then - DrawColumnText(aCol,aRow,aRect,aState); + + if TitleStyle=tsNative then begin + if gdFixed in aState then + DrawFixedText(aCol,aRow,aRect,aState) + else + DrawColumnText(aCol,aRow,aRect,aState); + end; end; procedure TCustomDBGrid.DrawCheckboxBitmaps(aCol: Integer; aRect: TRect; F: TField); +const + arrtb:array[TDbGridCheckboxState] of TThemedButton = + (tbCheckBoxUncheckedNormal, tbCheckBoxCheckedNormal, tbCheckBoxMixedNormal); var ChkBitmap: TBitmap; - XPos,YPos: Integer; + XPos,YPos,CSize: Integer; + AState: TDbGridCheckboxState; + details: TThemedElementDetails; + PaintRect: TRect; begin if (aCol=Col) and FDrawingActiveRecord then begin // show checkbox only if overriden editor is hidden @@ -2462,33 +2489,69 @@ begin end; // by SSY - if (F<>nil) then - if F.DataType=ftBoolean then + if (F<>nil) then + if F.DataType=ftBoolean then if F.IsNull then - ChkBitmap := GetImageForCheckBox(gcbpGrayed) + AState := gcbpGrayed else - if F.AsBoolean then - ChkBitmap := GetImageForCheckBox(gcbpChecked) - else - ChkBitmap := GetImageForCheckBox(gcbpUnChecked) + if F.AsBoolean then + AState := gcbpChecked + else + AState := gcbpUnChecked else if ValueMatch(F.AsString, TColumn(ColumnFromGridColumn(aCol)).ValueChecked) then - ChkBitmap := GetImageForCheckBox(gcbpChecked) + AState := gcbpChecked else - if ValueMatch(F.AsString, TColumn(ColumnFromGridColumn(aCol)).ValueUnChecked) then - ChkBitmap := GetImageForCheckBox(gcbpUnChecked) - else - ChkBitmap := GetImageForCheckBox(gcbpGrayed) + if ValueMatch(F.AsString, TColumn(ColumnFromGridColumn(aCol)).ValueUnChecked) then + AState := gcbpUnChecked + else + AState := gcbpGrayed else - ChkBitmap := GetImageForCheckBox(gcbpGrayed); - - if ChkBitmap<>nil then begin - XPos := Trunc((aRect.Left+aRect.Right-ChkBitmap.Width)/2); - YPos := Trunc((aRect.Top+aRect.Bottom-ChkBitmap.Height)/2); - Canvas.Draw(XPos, YPos, ChkBitmap); + AState := gcbpGrayed; + + if (TitleStyle=tsNative) and not assigned(OnUserCheckboxBitmap) then begin + Details := ThemeServices.GetElementDetails(arrtb[AState]); + CSize:= ThemeServices.GetDetailSize(Details); + with PaintRect do begin + Left := Trunc((aRect.Left + aRect.Right - CSize)/2); + Top := Trunc((aRect.Top + aRect.Bottom - CSize)/2); + PaintRect := Bounds(Left, Top, CSize, CSize); + end; + ThemeServices.DrawElement(Canvas.Handle, Details, PaintRect, nil); + end else begin + ChkBitmap := GetImageForCheckBox(AState); + if ChkBitmap<>nil then begin + XPos := Trunc((aRect.Left+aRect.Right-ChkBitmap.Width)/2); + YPos := Trunc((aRect.Top+aRect.Bottom-ChkBitmap.Height)/2); + Canvas.Draw(XPos, YPos, ChkBitmap); + end; end; end; +procedure TCustomDBGrid.DrawFixedText(aCol, aRow: Integer; aRect: TRect; + aState: TGridDrawState); + + function GetDatasetState: TDataSetState; + begin + if FDatalink.Active then + result := FDataLink.DataSet.State + else + result := dsInactive; + end; + +begin + if (ACol=0) and FDrawingActiveRecord then begin + DrawIndicator(Canvas, aRect, GetDataSetState, FDrawingMultiSelRecord); + {$ifdef dbgGridPaint} + dbgOut('>'); + {$endif} + end else + if (ACol=0) and FDrawingMultiSelRecord then + DrawIndicator(Canvas, aRect, dsCurValue{dummy}, True) + else + DrawColumnText(aCol, aRow, aRect, aState); +end; + function TCustomDBGrid.EditorCanAcceptKey(const ch: Char): boolean; var aField: TField; @@ -2689,33 +2752,21 @@ end; procedure TCustomDBGrid.DefaultDrawColumnCell(const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); - - function GetDatasetState: TDataSetState; - begin - if FDatalink.Active then - result := FDataLink.DataSet.State - else - result := dsInactive; - end; - var S: string; F: TField; begin - if gdFixed in State then begin - if (DataCol=0) and FDrawingActiveRecord then - DrawIndicator(Canvas, Rect, GetDataSetState, FDrawingMultiSelRecord) - else - if (DataCol=0) and FDrawingMultiSelRecord then - DrawIndicator(Canvas, Rect, dsCurValue{dummy}, True) - else - if (DataCol>=FixedCols) then - DrawCellText(0{dummy}, DataCol{dummy}, Rect, State,GetColumnTitle(DataCol)); - end else begin - F := GetFieldFromGridColumn(DataCol); + + F := Column.Field; + + DataCol := GridColumnFromColumnIndex(DataCol); + + if DataCol>=FixedCols then case ColumnEditorStyle(DataCol, F) of + cbsCheckBoxColumn: DrawCheckBoxBitmaps(DataCol, Rect, F); + else begin if F<>nil then begin if F.dataType <> ftBlob then @@ -2726,8 +2777,8 @@ begin S := ''; DrawCellText(0, DataCol, Rect, State, S); end; + end; - end; end; function TCustomDBGrid.EditorByStyle(Style: TColumnButtonStyle): TWinControl; diff --git a/lcl/grids.pas b/lcl/grids.pas index 862af66df4..d74f167e44 100644 --- a/lcl/grids.pas +++ b/lcl/grids.pas @@ -475,6 +475,7 @@ type function IndexOf(Column: TGridColumn): Integer; function IsDefault: boolean; function HasIndex(Index: Integer): boolean; + function VisibleIndex(Index: Integer): Integer; property Grid: TCustomGrid read FGrid; property Items[Index: Integer]: TGridColumn read GetColumn write SetColumn; default; property VisibleCount: Integer read GetVisibleCount; @@ -731,6 +732,7 @@ type procedure DoOPInsertColRow(IsColumn: boolean; index: integer); procedure DoOPMoveColRow(IsColumn: Boolean; FromIndex, ToIndex: Integer); procedure DoPasteFromClipboard; virtual; + procedure DoPrepareCanvas(aCol,aRow:Integer; aState: TGridDrawState); virtual; procedure DoSetBounds(ALeft, ATop, AWidth, AHeight: integer); override; procedure DrawBorder; procedure DrawAllRows; virtual; @@ -775,6 +777,7 @@ type function GetEditText(ACol, ARow: Longint): string; dynamic; function GetFixedcolor: TColor; virtual; function GetSelectedColor: TColor; virtual; + function GridColumnFromColumnIndex(ColumnIndex: Integer): Integer; procedure HeaderClick(IsColumn: Boolean; index: Integer); dynamic; procedure HeaderSized(IsColumn: Boolean; index: Integer); dynamic; @@ -2269,9 +2272,6 @@ var FGCache.AccumWidth[i]:=Pointer(PtrInt(FGCache.GridWidth)); FGCache.GridWidth:=FGCache.GridWidth + GetColWidths(i); if i-1)and(index