Files
HeidiSQL/source/vcl-styles-utils/Vcl.Styles.DbGrid.pas

254 lines
8.8 KiB
ObjectPascal

//**************************************************************************************************
//
// Unit Vcl.Styles.DbGrid
// unit for the VCL Styles Utils
// https://github.com/RRUZ/vcl-styles-utils/
//
// The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the
// License at http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
// ANY KIND, either express or implied. See the License for the specific language governing rights
// and limitations under the License.
//
// The Original Code is Vcl.Styles.DbGrid.pas.
//
// The Initial Developer of the Original Code is Rodrigo Ruz V.
// Portions created by Rodrigo Ruz V. are Copyright (C) 2012-2023 Rodrigo Ruz V.
// All Rights Reserved.
//
//**************************************************************************************************
unit Vcl.Styles.DbGrid;
interface
uses
Winapi.Windows,
Vcl.Grids,
Vcl.Graphics,
Vcl.DBGrids;
type
TDBGrid = class(Vcl.DBGrids.TDBGrid)
protected
procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
end;
implementation
uses
Data.DB,
System.SysUtils,
System.Classes,
System.UITypes,
Vcl.Forms,
Vcl.Styles,
Vcl.Themes,
Vcl.Controls;
type
TCustomGridClass = class(TCustomGrid);
TDbGridHelper = class helper for TCustomDBGrid
private
function GetTitleOffset: Byte;
function GetIndicators: TImageList;
function GetSelRow: Integer;
procedure SetSelRow(const Value: Integer);
public
property TitleOffset: Byte read GetTitleOffset;
property Indicators: TImageList read GetIndicators;
property SelRow: Integer read GetSelRow write SetSelRow;
end;
{ TDbGridHelper }
function TDbGridHelper.GetIndicators: TImageList;
begin
with Self do
Result := FIndicators;
end;
function TDbGridHelper.GetSelRow: Integer;
begin
with Self do
Result := FSelRow;
end;
function TDbGridHelper.GetTitleOffset: Byte;
begin
with Self do
Result := FTitleOffset;
end;
procedure TDbGridHelper.SetSelRow(const Value: Integer);
begin
with Self do
FSelRow := Value;
end;
procedure _WriteText(ACanvas: TCanvas; ARect: TRect; DX, DY: Integer; const AText: string; Alignment: TAlignment; ARightToLeft: Boolean);
var
X: Integer;
begin
if (ACanvas.CanvasOrientation = coRightToLeft) and (not ARightToLeft) then
ChangeBiDiModeAlignment(Alignment);
case Alignment of
taLeftJustify: X := ARect.Left + DX;
taRightJustify: X := ARect.Right - ACanvas.TextWidth(AText) - 3;
else
X := ARect.Left + (ARect.Right - ARect.Left) shr 1 - (ACanvas.TextWidth(AText) shr 1);
end;
ACanvas.TextRect(ARect, X, ARect.Top + DY, AText);
end;
{ TDBGrid }
procedure TDBGrid.DrawCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState);
var
OldActive: Integer;
Indicator: TThemedGrid;
Value: string;
CurrentColumn: TColumn;
MultiSelected: Boolean;
X: Integer;
LStyleServices: TCustomStyleServices;
DeltaX: Byte;
Index: Integer;
begin
LStyleServices := StyleServices;
if not TStyleManager.IsCustomStyleActive or (ARow-TitleOffset<0) then
begin
inherited DrawCell(ACol, ARow, ARect, AState);
exit;
end;
if csLoading in ComponentState then
begin
Canvas.Brush.Color := LStyleServices.GetStyleColor(scGrid);
Canvas.FillRect(ARect);
Exit;
end;
Dec(ARow, TitleOffset);
Dec(ACol, IndicatorOffset);
if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options =
[dgRowLines, dgColLines]) then
begin
Winapi.Windows.InflateRect(ARect, -1, -1);
DeltaX := 1;
end
else
DeltaX := 2;
if (gdFixed in AState) and (ACol < 0) then
begin
DrawCellBackground(ARect, FixedColor, AState, ACol, ARow);
if Assigned(DataLink) and DataLink.Active then
begin
MultiSelected := False;
if ARow >= 0 then
begin
OldActive := DataLink.ActiveRecord;
try
DataLink.ActiveRecord := ARow;
MultiSelected := (dgMultiSelect in Options) and Datalink.Active and SelectedRows.Find(Datalink.Datasource.Dataset.Bookmark, Index);;
finally
DataLink.ActiveRecord := OldActive;
end;
end;
if (ARow = DataLink.ActiveRecord) or MultiSelected then
begin
Indicator := tgIndicatorArrow;
if DataLink.DataSet <> nil then
case DataLink.DataSet.State of
dsEdit: Indicator := tgIndicatorEdit;
dsInsert: Indicator := tgIndicatorInsert;
dsBrowse:
if MultiSelected then
if (ARow <> DataLink.ActiveRecord) then
Indicator := tgIndicatorMultiDot
else
Indicator := tgIndicatorMultiArrow;
end;
Indicators.BkColor := FixedColor;
X := ARect.Right - Indicators.Width - DeltaX;
if Canvas.CanvasOrientation = coRightToLeft then
Inc(X);
if LStyleServices.Enabled and not LStyleServices.IsSystemStyle then
LStyleServices.DrawElement(Canvas.Handle, LStyleServices.GetElementDetails(Indicator), ARect)
else
Indicators.Draw(Canvas, X, (ARect.Top + ARect.Bottom - Indicators.Height) shr 1, Integer(Indicator) - Integer(tgIndicatorArrow), True);
if ARow = Datalink.ActiveRecord then
SelRow := ARow + TitleOffset;
end;
end;
end
else
with Canvas do
begin
CurrentColumn := Columns[ACol];
if not CurrentColumn.Showing then Exit;
if not (gdFixed in AState) then
begin
Font := CurrentColumn.Font;
Brush.Color := CurrentColumn.Color;
if (Brush.Color=LStyleServices.GetStyleColor(scGrid)) then
begin
Font.Color := LStyleServices.GetStyleFontColor(sfGridItemNormal);
Brush.Color := LStyleServices.GetStyleColor(scGrid);
end;
end;
if (DataLink = nil) or not DataLink.Active then
FillRect(ARect)
else
begin
Value := '';
OldActive := DataLink.ActiveRecord;
try
DataLink.ActiveRecord := ARow;
if Assigned(CurrentColumn.Field) then
Value := CurrentColumn.Field.DisplayText;
if HighlightCell(ACol, ARow, Value, AState) and DefaultDrawing then
DrawCellHighlight(ARect, AState, ACol, ARow);
if not Enabled then
Font.Color := clGrayText;
if DefaultDrawing then
_WriteText(Canvas, ARect, 3, 2, Value, CurrentColumn.Alignment, UseRightToLeftAlignmentForField(CurrentColumn.Field, CurrentColumn.Alignment));
if Columns.State = csDefault then
DrawDataCell(ARect, CurrentColumn.Field, AState);
DrawColumnCell(ARect, ACol, CurrentColumn, AState);
finally
DataLink.ActiveRecord := OldActive;
end;
Canvas.Brush.Style := bsSolid;
if DefaultDrawing and (gdSelected in AState) and ((dgAlwaysShowSelection in Options) or Focused)
and not (csDesigning in ComponentState) and not (dgRowSelect in Options)
and (UpdateLock = 0) and (ValidParentForm(Self).ActiveControl = Self) and
(FInternalDrawingStyle = gdsThemed) and (Win32MajorVersion >= 6) then
Winapi.Windows.InflateRect(ARect, -1, -1);
end;
end;
if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options =
[dgRowLines, dgColLines]) and (FInternalDrawingStyle = gdsClassic) and
not (gdPressed in AState) then
Winapi.Windows.InflateRect(ARect, 1, 1);
end;
end.