summaryrefslogtreecommitdiff
path: root/src/gui/fpg_basegrid.pas
diff options
context:
space:
mode:
authorGraeme Geldenhuys <graemeg@gmail.com>2014-08-20 02:11:13 +0100
committerGraeme Geldenhuys <graemeg@gmail.com>2014-08-20 02:11:13 +0100
commitc8acc2c1666015daeb3038c838e5018c0ecd8903 (patch)
tree5ad2edaf0e5fb6be146491226dca4d915333d80d /src/gui/fpg_basegrid.pas
parentc45010b6370b50f8e6192ddb7dc3d7762c8c29f7 (diff)
parentd0d8573b046e5020d05c86a970d303084de19b7d (diff)
downloadfpGUI-c8acc2c1666015daeb3038c838e5018c0ecd8903.tar.xz
Merge branch 'release-1.2' into master
Diffstat (limited to 'src/gui/fpg_basegrid.pas')
-rw-r--r--src/gui/fpg_basegrid.pas510
1 files changed, 399 insertions, 111 deletions
diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas
index 51b50408..cbce739f 100644
--- a/src/gui/fpg_basegrid.pas
+++ b/src/gui/fpg_basegrid.pas
@@ -1,7 +1,7 @@
{
fpGUI - Free Pascal GUI Toolkit
- Copyright (C) 2006 - 2012 See the file AUTHORS.txt, included in this
+ Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this
distribution, for details of the copyright.
See the file COPYING.modifiedLGPL, included in this distribution,
@@ -40,6 +40,7 @@ type
TfpgGridHeaderStyle = (ghsButton, ghsThin, ghsFlat);
TfpgFocusChangeNotify = procedure(Sender: TObject; ARow, ACol: Integer) of object;
+ TfpgHeaderClick = procedure(Sender: TObject; ACol: Integer) of object;
TfpgRowChangeNotify = procedure(Sender: TObject; ARow: Integer) of object;
TfpgCanSelectCellEvent = procedure(Sender: TObject; const ARow, ACol: Integer; var ACanSelect: boolean) of object;
TfpgDrawCellEvent = procedure(Sender: TObject; const ARow, ACol: Integer; const ARect: TfpgRect; const AFlags: TfpgGridDrawState; var ADefaultDrawing: boolean) of object;
@@ -50,12 +51,14 @@ type
// Column 2 is special just for testing purposes. Descendant classes will
// override that special behavior anyway.
+
TfpgBaseGrid = class(TfpgWidget)
private
FColResizing: boolean;
FDragPos: integer; // used for column resizing
FHeaderStyle: TfpgGridHeaderStyle;
FOnDrawCell: TfpgDrawCellEvent;
+ FOnHeaderClick: TfpgHeaderClick;
FResizedCol: integer; // used for column resizing
FDefaultColWidth: integer;
FDefaultRowHeight: integer;
@@ -70,7 +73,6 @@ type
FFirstRow: Integer;
FFirstCol: Integer;
FXOffset: integer; // used for go_SmoothScroll
- FMargin: integer;
FFont: TfpgFont;
FHeaderFont: TfpgFont;
FRowSelect: boolean;
@@ -88,6 +90,7 @@ type
function GetFontDesc: string;
function GetHeaderFontDesc: string;
function GetTotalColumnWidth: integer;
+ function GetAdjustedBorderSizes: TRect;
procedure HScrollBarMove(Sender: TObject; position: integer);
procedure SetFontDesc(const AValue: string);
procedure SetHeaderFontDesc(const AValue: string);
@@ -103,8 +106,6 @@ type
procedure SetShowGrid(const AValue: boolean);
procedure SetShowHeader(const AValue: boolean);
function VisibleLines: Integer;
- function VisibleWidth: integer;
- function VisibleHeight: integer;
procedure SetFirstRow(const AValue: Integer);
procedure SetAlternativeBGColor(const AValue: TfpgColor);
procedure SetBorderStyle(AValue: TfpgEditBorderStyle);
@@ -132,11 +133,13 @@ type
procedure HandleResize(awidth, aheight: TfpgCoord); override;
procedure HandleKeyPress(var keycode: word; var shiftstate: TShiftState; var consumed: boolean); override;
procedure HandleMouseScroll(x, y: integer; shiftstate: TShiftState; delta: smallint); override;
+ procedure HandleMouseHorizScroll(x, y: integer; shiftstate: TShiftState; delta: smallint); override;
procedure HandleMouseMove(x, y: integer; btnstate: word; shiftstate: TShiftState); override;
procedure HandleLMouseUp(x, y: integer; shiftstate: TShiftState); override;
procedure HandleLMouseDown(x, y: integer; shiftstate: TShiftState); override;
procedure HandleRMouseUp(x, y: integer; shiftstate: TShiftState); override;
procedure FollowFocus; virtual;
+ procedure PrepareCells (firstrow, lastrow, firstcol, lastcol : integer); virtual;
property AlternateBGColor: TfpgColor read FAlternativeBGColor write SetAlternativeBGColor default clHilite1;
property BorderStyle: TfpgEditBorderStyle read FBorderStyle write SetBorderStyle default ebsDefault;
property DefaultColWidth: integer read FDefaultColWidth write SetDefaultColWidth default 64;
@@ -166,6 +169,7 @@ type
property Options: TfpgGridOptions read FOptions write FOptions default [];
property OnDrawCell: TfpgDrawCellEvent read FOnDrawCell write FOnDrawCell;
property OnFocusChange: TfpgFocusChangeNotify read FOnFocusChange write FOnFocusChange;
+ property OnHeaderClick: TfpgHeaderClick read FOnHeaderClick write FOnHeaderClick;
property OnRowChange: TfpgRowChangeNotify read FOnRowChange write FOnRowChange;
property OnCanSelectCell: TfpgCanSelectCellEvent read FOnCanSelectCell write FOnCanSelectCell;
public
@@ -176,6 +180,9 @@ type
procedure BeginUpdate;
procedure EndUpdate;
procedure MouseToCell(X, Y: Integer; var ACol, ARow: Integer);
+ function GetClientRect: TfpgRect; override;
+ function VisibleWidth: integer;
+ function VisibleHeight: integer;
end;
@@ -226,6 +233,32 @@ begin
Result := Result + ColumnWidth[i];
end;
+// Adjust theme borders based on BorderStyle property
+function TfpgBaseGrid.GetAdjustedBorderSizes: TRect;
+begin
+ Result := fpgStyle.GetControlFrameBorders;
+ case BorderStyle of
+ ebsNone:
+ begin
+ Result.Left := 0;
+ Result.Right := 0;
+ Result.Top := 0;
+ Result.Bottom := 0;
+ end;
+ ebsDefault:
+ begin
+ // do nothing - the theme values are correct
+ end;
+ ebsSingle:
+ begin
+ Result.Left := 1;
+ Result.Right := 1;
+ Result.Top := 1;
+ Result.Bottom := 1;
+ end;
+ end;
+end;
+
procedure TfpgBaseGrid.SetFontDesc(const AValue: string);
begin
FFont.Free;
@@ -528,7 +561,7 @@ begin
hh := 0;
if ShowHeader then
hh := hh + FHeaderHeight+1;
- Result := (Height - (2*FMargin) - hh) div FDefaultRowHeight;
+ Result := (GetClientRect.Height - hh) div FDefaultRowHeight;
end;
function TfpgBaseGrid.VisibleWidth: integer;
@@ -536,10 +569,10 @@ var
sw: integer;
begin
if FVScrollBar.Visible then
- sw := FVScrollBar.Width-1
+ sw := FVScrollBar.Width
else
sw := 0;
- Result := Width - (FMargin*2) - sw;
+ Result := GetClientRect.Width - sw
end;
function TfpgBaseGrid.VisibleHeight: integer;
@@ -547,10 +580,10 @@ var
sw: integer;
begin
if FHScrollBar.Visible then
- sw := FHScrollBar.Height-1
+ sw := FHScrollBar.Height
else
sw := 0;
- Result := Height - (FMargin*2) - sw;
+ Result := GetClientRect.Height - sw;
end;
procedure TfpgBaseGrid.SetFirstRow(const AValue: Integer);
@@ -585,76 +618,186 @@ var
VHeight: integer;
vw: integer;
cw: integer;
+ vl: integer;
i: integer;
x: integer;
-begin
- VHeight := Height - 4;
- HWidth := Width - 4;
-
- vw := VisibleWidth;
- cw := 0;
- for i := 0 to ColumnCount-1 do
- cw := cw + ColumnWidth[i];
-
- // This needs improving while resizing
- if cw > vw then
- FHScrollBar.Visible := not (FScrollBarStyle in [ssNone, ssVertical])
- else
+ hmax: integer;
+ vmax: integer;
+ Hfits, showH : boolean;
+ Vfits, showV : boolean;
+ crect: TfpgRect;
+ borders: TRect;
+
+ procedure hideScrollbar (sb : TfpgScrollBar);
begin
- FHScrollBar.Visible := False;
- FFirstCol := 0;
- FXOffset := 0;
+ with sb do
+ if Visible then
+ begin
+ Visible := False;
+ UpdateWindowPosition;
+ end;
end;
- // This needs improving while resizing
- if (RowCount > VisibleLines) then
- FVScrollBar.Visible := not (FScrollBarStyle in [ssNone, ssHorizontal])
- else
+ procedure getVisWidth;
begin
- FVScrollBar.Visible := False;
- FFirstRow := 0;
+ if showV then
+ vw := HWidth - (FVScrollBar.Width-1)
+ else
+ vw := HWidth;
+ Hfits := vw >= cw;
end;
- if FVScrollBar.Visible then
+ procedure getVisLines;
+ var
+ hh : integer; // header height
begin
+ hh := 0;
+ if ShowHeader then
+ inc (hh, FHeaderHeight+1);
+ if showH then
+ inc (hh, FHScrollBar.Height);
+ vl := (VHeight - hh) div FDefaultRowHeight;
+ Vfits := vl >= RowCount;
+ end;
+
+begin
+ // if we don't want any scrollbars, hide them and exit
+ if FScrollBarStyle = ssNone then
+ begin
+ hideScrollbar(FHScrollBar);
+ hideScrollbar(FVScrollBar);
+ exit;
+ end;
+
+ borders := GetAdjustedBorderSizes;
+ // preliminary width/height calculations
+ crect := GetClientRect;
+ VHeight := crect.Height;
+ HWidth := crect.Width;
+ cw := 0;
+ for i := 0 to ColumnCount-1 do
+ cw := cw + ColumnWidth[i];
+ showV := False;
+ showH := False;
+ getVisWidth;
+ getVisLines;
+
+ // determine whether to show scrollbars for different configurations
+ case FScrollBarStyle of
+ ssHorizontal:
+ begin
+ hideScrollbar (FVScrollBar);
+ if not Hfits then
+ begin
+ showH := true;
+ getVisLines;
+ end;
+ end;
+ ssVertical:
+ begin
+ hideScrollbar (FHScrollBar);
+ if not Vfits then
+ begin
+ showV := true;
+ getVisWidth;
+ end;
+ end;
+ ssAutoBoth:
+ if not Vfits then
+ begin
+ showV := true;
+ getVisWidth;
+ if not Hfits then
+ begin
+ showH := true;
+ getVisLines;
+ getVisWidth;
+ end;
+ end
+ else if not Hfits then
+ begin
+ showH := true;
+ getVisLines;
+ if not Vfits then
+ begin
+ showV := true;
+ getVisWidth;
+ getVisLines;
+ end;
+ end;
+ end;
+
+ // set the scrollbar width/height space
+ if showV then
Dec(HWidth, FVScrollBar.Width);
- FVScrollBar.Min := 0;
+ if showH then
+ Dec(VHeight, FHScrollBar.Height);
+
+ // show or hide the scrollbars
+
+ if showV then
+ begin
+ FVScrollBar.Visible := true;
+ FVScrollBar.Min := 0;
if RowCount > 0 then
FVScrollBar.SliderSize := VisibleLines / RowCount
else
FVScrollBar.SliderSize := 0;
- FVScrollBar.Max := RowCount-VisibleLines;
- FVScrollBar.Position := FFirstRow;
+ vmax := RowCount - VisibleLines;
+ if FFirstRow > vmax then
+ FFirstRow := vmax;
+ FVScrollBar.Max := vmax;
+ FVScrollBar.Position := FFirstRow;
FVScrollBar.RepaintSlider;
+ FVScrollBar.Top := borders.Top;
+ FVScrollBar.Left := Width - FVScrollBar.Width - borders.Right;
+ FVScrollBar.Height := VHeight;
+ end
+ else
+ begin
+ FVScrollBar.Visible := false;
+ if Vfits then
+ FFirstRow := 0;
+ // if vertical doesn't fit and no scrollbar, do not change firstrow
end;
-
- if FHScrollBar.Visible then
+
+ if showH then
begin
- Dec(VHeight, FHScrollBar.Height);
+ FHScrollBar.Visible := true;
FHScrollBar.Min := 0;
if go_SmoothScroll in FOptions then
begin
- FHScrollBar.Max := cw - vw;
+ hmax := cw - vw;
+ FHScrollBar.Max := hmax;
+ if FXOffset>hmax then
+ FXOffset:=hmax;
FHScrollBar.Position := FXOffset;
- FHScrollBar.SliderSize := Width / TotalColumnWidth;
+ FHScrollBar.SliderSize := HWidth / TotalColumnWidth;
+ FHScrollBar.PageSize := 5;
end
else
begin
FHScrollBar.Max := ColumnCount-1;
FHScrollBar.Position := FFirstCol;
- FHScrollBar.SliderSize := 1 / ColumnCount;
+ FHScrollBar.SliderSize := 1 / ColumnCount;
+ FHScrollBar.PageSize := 1;
end;
FHScrollBar.RepaintSlider;
+ FHScrollBar.Top := Height - FHScrollBar.Height - borders.Bottom;
+ FHScrollBar.Left := borders.Left;
+ FHScrollBar.Width := HWidth;
+ end
+ else
+ begin
+ FHScrollBar.Visible := False;
+ if Hfits then
+ begin
+ FFirstCol := 0;
+ FXOffset := 0;
+ end;
+ // if horizontal doesn't fit and no scrollbar, do not change firstcol/xoffset
end;
- FHScrollBar.Top := Height -FHScrollBar.Height - 2;
- FHScrollBar.Left := 2;
- FHScrollBar.Width := HWidth;
-
- FVScrollBar.Top := 2;
- FVScrollBar.Left := Width - FVScrollBar.Width - 2;
- FVScrollBar.Height := VHeight;
-
FVScrollBar.UpdateWindowPosition;
FHScrollBar.UpdateWindowPosition;
end;
@@ -673,10 +816,12 @@ var
clipr: TfpgRect; // clip rectangle
drawstate: TfpgGridDrawState;
cLeft: integer;
- c: integer;
+ rTop: integer;
+ firstcol, lastcol, firstrow, lastrow : integer;
+ cWidths: array of integer;
+ rect: TRect;
begin
Canvas.ClearClipRect;
-
r.SetRect(0, 0, Width, Height);
case BorderStyle of
ebsNone:
@@ -685,51 +830,103 @@ begin
end;
ebsDefault:
begin
- Canvas.DrawControlFrame(r);
- InflateRect(r, -2, -2);
+ fpgStyle.DrawControlFrame(Canvas, r);
end;
ebsSingle:
begin
Canvas.SetColor(clShadow2);
Canvas.DrawRectangle(r);
- InflateRect(r, -1, -1);
end;
end;
- Canvas.SetClipRect(r);
+ r := GetClientRect;
+ clipr := r;
+ Canvas.SetClipRect(clipr);
Canvas.SetColor(FBackgroundColor);
Canvas.FillRectangle(r);
- clipr.SetRect(FMargin, FMargin, VisibleWidth, VisibleHeight);
- r := clipr;
+ cLeft := r.Left; // column starting point
+ rTop := r.Top; // row starting point
- cLeft := FMargin; // column starting point
if go_SmoothScroll in FOptions then
begin
if FHScrollBar.Visible then
Dec(cLeft, FHScrollBar.Position);
- c := 0;
+ firstcol := 0;
end
else
begin
- c := FFirstCol;
+ firstcol := FFirstCol;
end;
+ // calculate column widths, and first/last columns
+ if (ColumnCount <= 0) then
+ begin
+ firstcol := -1;
+ lastcol := -2;
+ end
+ else
+ begin
+ setlength (cWidths, ColumnCount);
+ r.Left := cLeft;
+ for col := firstcol to ColumnCount-1 do
+ begin
+ cWidths[col] := ColumnWidth[col];
+ r.Width := cWidths[col];
+ if (go_SmoothScroll in FOptions) and (r.Left <= clipr.Left) then
+ begin
+ firstcol := col;
+ if col>0 then inc (cLeft, cWidths[col-1]);
+ end;
+ lastcol := col;
+ if r.Right >= clipr.Right then
+ break;
+ inc (r.Left, r.Width);
+ end;
+ // first/last rows...
+ if (RowCount <= 0) then
+ begin
+ firstrow := -1;
+ lastrow := -2;
+ end
+ else
+ begin
+ if ShowHeader then
+ inc (r.Top, FHeaderHeight);
+ if r.Top > clipr.Bottom then
+ begin
+ firstrow := -1;
+ lastrow := -2;
+ end
+ else
+ begin
+ firstrow := FFirstRow;
+ lastrow := firstrow + (clipr.Bottom - r.Top) div DefaultRowHeight;
+ if lastrow >= RowCount then
+ lastrow := RowCount-1;
+ end;
+ end;
+ end;
+
+ PrepareCells (firstrow, lastrow, firstcol, lastcol);
+
+ r.Left := cLeft;
+ r.Top := rTop;
+
if (ColumnCount > 0) and ShowHeader then
begin
// Drawing horizontal headers
- r.Left := cLeft;
r.Height := FHeaderHeight;
Canvas.SetFont(FHeaderFont);
- for col := c to ColumnCount-1 do
+ for col := firstcol to lastcol do
begin
- r.Width := ColumnWidth[col];
+ r.Width := cWidths[col];
Canvas.SetClipRect(clipr);
Canvas.AddClipRect(r);
DrawHeader(col, r, 0);
inc(r.Left, r.Width);
- if r.Left >= clipr.Right then
- Break; // small optimization. Don't draw what we can't see
+ //if r.Left >= clipr.Right then
+ // Break; // optimization made obsolete by lastcol
end;
inc(r.Top, r.Height);
end;
@@ -740,13 +937,13 @@ begin
r.Height := DefaultRowHeight;
Canvas.SetFont(FFont);
- for row := FFirstRow to RowCount-1 do
+ for row := firstrow to lastrow do
begin
r.Left := cLeft;
- for col := c to ColumnCount-1 do
+ for col := firstcol to lastcol do
begin
drawstate := [];
- r.Width := ColumnWidth[col];
+ r.Width := cWidths[col];
Canvas.SetClipRect(clipr);
if (row = FFocusRow) and (RowSelect or (col = FFocusCol)) and not (go_HideFocusRect in FOptions) then
@@ -774,7 +971,6 @@ begin
Include(drawstate, gdFocused);
if (row = FFocusRow) and (col = FFocusCol) then
Include(drawstate, gdSelected);
-
if DoDrawCellEvent(row, col, r, drawstate) then
DrawCell(row, col, r, drawstate);
@@ -783,13 +979,13 @@ begin
DrawGrid(row, col, r, 0);
inc(r.Left, r.Width);
- if r.Left >= clipr.Right then
- Break; // small optimization. Don't draw what we can't see
+ //if r.Left >= clipr.Right then
+ // Break; // optimization made obsolete by lastcol
end;
// Inc(r.Top, FDefaultRowHeight+1);
inc(r.Top, r.Height);
- if r.Top >= clipr.Bottom then
- break;
+ //if r.Top >= clipr.Bottom then
+ // break; // optimization made obsolete by lastrow
end;
end; // item drawing
@@ -1008,49 +1204,66 @@ end;
procedure TfpgBaseGrid.HandleMouseScroll(x, y: integer; shiftstate: TShiftState; delta: smallint);
var
lRow: Integer;
- lCol: Integer;
begin
inherited HandleMouseScroll(x, y, shiftstate, delta);
lRow := FFirstRow;
- lCol := FFirstCol;
- if delta > 0 then // scroll down
- inc(FFirstRow, abs(delta)*3)
- else // scroll up
- if FFirstRow > 0 then
- dec(FFirstRow, abs(delta)*3);
+ // If vertical scrollbar is not visible, but
+ // horizontal is, Mouse wheel will scroll horizontally. :)
+ if FHScrollBar.Visible and (not FVScrollBar.Visible) then
+ begin
+ HandleMouseHorizScroll(x, y, shiftstate, delta);
+ Exit;
+ end;
+
+ inc(FFirstRow, delta*3);
// apply limits
if FFirstRow > RowCount - VisibleLines then
FFirstRow := RowCount - VisibleLines;
if FFirstRow < 0 then
FFirstRow := 0;
-
- // scroll left/right
- // If vertical scrollbar is not visible, but
- // horizontal is. Mouse wheel will scroll horizontally. :)
- if FHScrollBar.Visible and (not FVScrollBar.Visible) then
- begin
- if delta > 0 then // scroll right
- begin
- if FFirstCol < (ColumnCount-1) then
- inc(FFirstCol);
- end
- else
- begin
- if FFirstCol > 0 then
- dec(FFirstCol);
- end;
- end;
- if (lRow <> FFirstRow) or (lCol <> FFirstCol) then
+ if lRow <> FFirstRow then
begin
UpdateScrollBars;
RePaint;
end;
end;
+procedure TfpgBaseGrid.HandleMouseHorizScroll(x, y: integer; shiftstate: TShiftState; delta: smallint);
+var
+ old_val: Integer;
+begin
+ inherited HandleMouseHorizScroll(x, y, shiftstate, delta);
+
+ if go_SmoothScroll in Options then
+ begin
+ old_val := FXOffset;
+ inc(FXOffset, delta*FHScrollBar.ScrollStep);
+ if (FXOffset<0) then
+ FXOffset:=0;
+ // finding the maximum Xoffset is tricky, let updatescrollbars do it.
+ if (FXOffset=old_val) then
+ Exit;
+ end
+ else
+ begin
+ old_val := FFirstCol;
+ inc(FFirstCol, delta);
+ if FFirstCol<0 then
+ FFirstCol:=0
+ else if FFirstCol > ColumnCount-1 then
+ FFirstCol:=ColumnCount-1;
+ if FFirstCol=old_val then
+ Exit;
+ end;
+
+ UpdateScrollBars;
+ RePaint;
+end;
+
procedure TfpgBaseGrid.HandleMouseMove(x, y: integer; btnstate: word; shiftstate: TShiftState);
var
hh: integer;
@@ -1059,6 +1272,7 @@ var
colresize: boolean;
cLeft: integer;
c: integer;
+ borders: TRect;
begin
inherited HandleMouseMove(x, y, btnstate, shiftstate);
@@ -1082,8 +1296,9 @@ begin
begin
colresize := False;
hh := FHeaderHeight;
+ borders := GetAdjustedBorderSizes;
- cLeft := FMargin; // column starting point
+ cLeft := borders.Left; // column starting point
if go_SmoothScroll in FOptions then
begin
if FHScrollBar.Visible then
@@ -1095,7 +1310,7 @@ begin
c := FFirstCol;
end;
- if (y <= FMargin + hh) then // we are over the Header row
+ if (y <= (borders.Top + hh)) then // we are over the Header row
begin
cw := 0;
for n := c to ColumnCount-1 do
@@ -1120,12 +1335,62 @@ begin
end;
procedure TfpgBaseGrid.HandleLMouseUp(x, y: integer; shiftstate: TShiftState);
+var
+ lColumn: integer;
+ hh: integer; { header height }
+ cLeft: integer; { column left }
+ c: integer;
+ n: integer;
+ cw: integer;
+ borders: TRect;
begin
inherited HandleLMouseUp(x, y, shiftstate);
+ if not FColResizing then
+ begin
+ if not ShowHeader then
+ Exit;
+ if (ColumnCount = 0) then
+ Exit; //==>
+ // searching for the appropriate character position
+ hh := FHeaderHeight;
+ borders := GetAdjustedBorderSizes;
+
+ if (y < (borders.Top+hh)) then // inside Header row
+ begin
+ {$IFDEF DEBUG} Writeln('header click...'); {$ENDIF}
+
+ cLeft := borders.Left; // column starting point
+ if go_SmoothScroll in FOptions then
+ begin
+ if FHScrollBar.Visible then
+ Dec(cLeft, FHScrollBar.Position);
+ c := 0;
+ end
+ else
+ begin
+ c := FFirstCol;
+ end;
+
+ cw := 0;
+ for n := c to ColumnCount-1 do
+ begin
+ inc(cw, ColumnWidth[n]);
+ if x < (cLeft+cw+4) then
+ begin
+ if Assigned(FOnHeaderClick) then
+ FOnHeaderClick(self, n);
+ Break;
+ end;
+ end; { for }
+ end;
+ end; {if not FColResizing }
+
{$IFDEF DEBUG}
if FColResizing then
+ begin
Writeln('Column ', FResizedCol,' width = ', ColumnWidth[FResizedCol]);
+ end;
{$ENDIF}
FColResizing := False;
@@ -1142,6 +1407,7 @@ var
pcol: Integer;
c: integer;
cLeft: integer;
+ borders: TRect;
begin
inherited HandleLMouseDown(x, y, shiftstate);
@@ -1150,18 +1416,19 @@ begin
pcol := FFocusCol;
prow := FFocusRow;
+ borders := GetAdjustedBorderSizes;
// searching for the appropriate character position
if ShowHeader then
- hh := FHeaderHeight+1
+ hh := FHeaderHeight
else
hh := 0;
- if ShowHeader and (y <= FMargin+hh) then // inside Header row
+ if ShowHeader and (y < (borders.Top+hh)) then // inside Header row
begin
{$IFDEF DEBUG} Writeln('header click...'); {$ENDIF}
- cLeft := FMargin; // column starting point
+ cLeft := borders.Left; // column starting point
if go_SmoothScroll in FOptions then
begin
if FHScrollBar.Visible then
@@ -1226,7 +1493,7 @@ begin
else
hh := 0;
- if ShowHeader and (y > FMargin+hh) then // not in Header row
+ if ShowHeader and (y > (fpgStyle.GetControlFrameBorders.Top + hh)) then // not in Header row
begin
PopupMenu.ShowAt(self, x, y);
end;
@@ -1268,7 +1535,7 @@ begin
w := 0;
for n := FFocusCol downto FFirstCol do
begin
- w := w + ColumnWidth[n]+1;
+ w := w + ColumnWidth[n];
if w > VisibleWidth then
begin
if n = FFocusCol then
@@ -1283,7 +1550,14 @@ begin
UpdateScrollBars;
end;
+procedure TfpgBaseGrid.PrepareCells(firstrow, lastrow, firstcol, lastcol: integer);
+begin
+ // for descendents
+end;
+
constructor TfpgBaseGrid.Create(AOwner: TComponent);
+var
+ borders: TRect;
begin
Updating;
inherited Create(AOwner);
@@ -1296,7 +1570,6 @@ begin
FPrevRow := -1;
FFirstRow := 0;
FFirstCol := 0;
- FMargin := 2;
FShowHeader := True;
FShowGrid := True;
FRowSelect := False;
@@ -1306,6 +1579,8 @@ begin
FHeaderStyle := ghsButton;
FBorderStyle := ebsDefault;
+ borders := GetAdjustedBorderSizes;
+
FFont := fpgGetFont('#Grid');
FHeaderFont := fpgGetFont('#GridHeader');
@@ -1317,8 +1592,8 @@ begin
FAlternativeBGColor := clHilite1;
FColResizing := False;
- MinHeight := HeaderHeight + DefaultRowHeight + FMargin;
- MinWidth := DefaultColWidth + FMargin;
+ MinHeight := HeaderHeight + DefaultRowHeight + borders.Top + borders.Bottom;
+ MinWidth := DefaultColWidth + borders.Left + borders.Right;
FVScrollBar := TfpgScrollBar.Create(self);
FVScrollBar.Orientation := orVertical;
@@ -1329,7 +1604,7 @@ begin
FHScrollBar.Orientation := orHorizontal;
FHScrollBar.Visible := False;
FHScrollBar.OnScroll := @HScrollBarMove;
- FHScrollBar.ScrollStep := 5;
+ FHScrollBar.ScrollStep := 20;
end;
destructor TfpgBaseGrid.Destroy;
@@ -1388,11 +1663,11 @@ begin
else
hh := 0;
- ARow := FFirstRow + ((y - FMargin - hh) div FDefaultRowHeight);
+ ARow := FFirstRow + ((y - fpgStyle.GetControlFrameBorders.Top - hh) div FDefaultRowHeight);
if ARow > RowCount-1 then
ARow := RowCount-1;
- cLeft := FMargin; // column starting point
+ cLeft := fpgStyle.GetControlFrameBorders.Left; // column starting point
if go_SmoothScroll in FOptions then
begin
if FHScrollBar.Visible then
@@ -1416,6 +1691,19 @@ begin
end;
end;
+function TfpgBaseGrid.GetClientRect: TfpgRect;
+var
+ rect: TRect;
+begin
+ Result := inherited GetClientRect;
+ rect := fpgStyle.GetControlFrameBorders;
+ case BorderStyle of
+// ebsNone: // nothing to do
+ ebsDefault: InflateRect(Result, -rect.Left, -rect.Top); { assuming borders are even on opposite sides }
+ ebsSingle: InflateRect(Result, -1, -1);
+ end;
+end;
+
end.