From 701873c5a99b5e4c24290efc7f07bfeda5d87cd9 Mon Sep 17 00:00:00 2001 From: David Laurence Emerson Date: Wed, 17 Apr 2013 19:11:44 -0700 Subject: Grids: improve UpdateScrollbars for resizing etc --- src/gui/fpg_basegrid.pas | 122 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas index 51b50408..d7d6a6c6 100644 --- a/src/gui/fpg_basegrid.pas +++ b/src/gui/fpg_basegrid.pas @@ -585,34 +585,128 @@ var VHeight: integer; vw: integer; cw: integer; + vl: integer; i: integer; x: integer; + Hfits, showH : boolean; + Vfits, showV : boolean; + + procedure hideScrollbar (sb : TfpgScrollBar); + begin + with sb do + if Visible then + begin + Visible := False; + UpdateWindowPosition; + end; + end; + + procedure getVisWidth; + begin + if showV then + vw := HWidth - (FVScrollBar.Width-1) + else + vw := HWidth; + Hfits := vw >= cw; + end; + + 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; + + // preliminary width/height calculations VHeight := Height - 4; HWidth := Width - 4; - - vw := VisibleWidth; 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; - // This needs improving while resizing - if cw > vw then - FHScrollBar.Visible := not (FScrollBarStyle in [ssNone, ssVertical]) + if showH then + FHScrollBar.Visible := true else begin - FHScrollBar.Visible := False; - FFirstCol := 0; - FXOffset := 0; + 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; - - // This needs improving while resizing - if (RowCount > VisibleLines) then - FVScrollBar.Visible := not (FScrollBarStyle in [ssNone, ssHorizontal]) + + if showV then + FVScrollBar.Visible := true else begin - FVScrollBar.Visible := False; - FFirstRow := 0; + FVScrollBar.Visible := false; + if Vfits then + FFirstRow := 0; + // if vertical doesn't fit and no scrollbar, do not change firstrow end; if FVScrollBar.Visible then -- cgit v1.2.3-70-g09d2 From c0bbd17213034ceda7f078ac1d2adb0d5561a7d7 Mon Sep 17 00:00:00 2001 From: David Laurence Emerson Date: Wed, 17 Apr 2013 22:45:01 -0700 Subject: Grids: basegrid updateScrollbars almost done --- src/gui/fpg_basegrid.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas index d7d6a6c6..42e92053 100644 --- a/src/gui/fpg_basegrid.pas +++ b/src/gui/fpg_basegrid.pas @@ -730,7 +730,7 @@ begin begin FHScrollBar.Max := cw - vw; FHScrollBar.Position := FXOffset; - FHScrollBar.SliderSize := Width / TotalColumnWidth; + FHScrollBar.SliderSize := HWidth / TotalColumnWidth; end else begin -- cgit v1.2.3-70-g09d2 From f95f261dc0a36fc387cc7295d68cafc71410b0c9 Mon Sep 17 00:00:00 2001 From: David Laurence Emerson Date: Wed, 17 Apr 2013 22:47:05 -0700 Subject: Grids: basegrid updateScrollbars done? --- src/gui/fpg_basegrid.pas | 66 ++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas index 42e92053..c86f3bb5 100644 --- a/src/gui/fpg_basegrid.pas +++ b/src/gui/fpg_basegrid.pas @@ -686,32 +686,17 @@ begin end; end; + // set the scrollbar width/height space + if showV then + Dec(HWidth, FVScrollBar.Width); if showH then - FHScrollBar.Visible := true - 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; + Dec(VHeight, FHScrollBar.Height); - if showV then - FVScrollBar.Visible := true - else - begin - FVScrollBar.Visible := false; - if Vfits then - FFirstRow := 0; - // if vertical doesn't fit and no scrollbar, do not change firstrow - end; + // show or hide the scrollbars - if FVScrollBar.Visible then + if showV then begin - Dec(HWidth, FVScrollBar.Width); + FVScrollBar.Visible := true; FVScrollBar.Min := 0; if RowCount > 0 then FVScrollBar.SliderSize := VisibleLines / RowCount @@ -720,11 +705,21 @@ begin FVScrollBar.Max := RowCount-VisibleLines; FVScrollBar.Position := FFirstRow; FVScrollBar.RepaintSlider; + FVScrollBar.Top := 2; + FVScrollBar.Left := Width - FVScrollBar.Width - 2; + 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 @@ -739,16 +734,21 @@ begin FHScrollBar.SliderSize := 1 / ColumnCount; end; FHScrollBar.RepaintSlider; + FHScrollBar.Top := Height -FHScrollBar.Height - 2; + FHScrollBar.Left := 2; + 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; -- cgit v1.2.3-70-g09d2 From 499be68f396eb7d31c835f57762b7175c56ded9a Mon Sep 17 00:00:00 2001 From: David Laurence Emerson Date: Thu, 18 Apr 2013 00:51:02 -0700 Subject: Grids: basegrid pre calculation, not drawing right --- src/gui/fpg_basegrid.pas | 86 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas index c86f3bb5..e7b98f98 100644 --- a/src/gui/fpg_basegrid.pas +++ b/src/gui/fpg_basegrid.pas @@ -767,7 +767,9 @@ var clipr: TfpgRect; // clip rectangle drawstate: TfpgGridDrawState; cLeft: integer; - c: integer; + rTop: integer; + firstcol, lastcol, firstrow, lastrow : integer; + cWidths: array of integer; begin Canvas.ClearClipRect; @@ -798,32 +800,86 @@ begin r := clipr; cLeft := FMargin; // column starting point + rTop := FMargin; // row 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 and rows + 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[firstcol] := ColumnWidth[col]; + r.Width := cWidths[firstcol]; + lastcol := col; + if (go_SmoothScroll in FOptions) and (r.Left <= clipr.Left) then + firstcol := col; + if r.Right >= clipr.Right then + break; + inc (r.Left, r.Width); + end; + 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; + for row := firstrow to RowCount-1 do + begin + inc (r.Top, DefaultRowHeight); + if r.Top >= clipr.Bottom then + break; + lastrow := row; + end; + end; + end; end; + 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 firstcol/lastcol end; inc(r.Top, r.Height); end; @@ -834,13 +890,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 @@ -877,13 +933,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; // small optimization. Don't draw what we can't see 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; end; end; // item drawing -- cgit v1.2.3-70-g09d2 From fdbee2022e3ef8d514d951ac31872f69aa431084 Mon Sep 17 00:00:00 2001 From: David Laurence Emerson Date: Thu, 18 Apr 2013 15:09:31 -0700 Subject: Grids: basegrid drawing right! Created PrepareCells function. Still preparing too many cells. --- src/gui/fpg_basegrid.pas | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas index e7b98f98..c8e93092 100644 --- a/src/gui/fpg_basegrid.pas +++ b/src/gui/fpg_basegrid.pas @@ -50,6 +50,9 @@ type // Column 2 is special just for testing purposes. Descendant classes will // override that special behavior anyway. + + { TfpgBaseGrid } + TfpgBaseGrid = class(TfpgWidget) private FColResizing: boolean; @@ -137,6 +140,7 @@ type 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; @@ -825,12 +829,15 @@ begin r.Left := cLeft; for col := firstcol to ColumnCount-1 do begin - cWidths[firstcol] := ColumnWidth[col]; + cWidths[col] := ColumnWidth[col]; r.Width := cWidths[firstcol]; lastcol := col; if (go_SmoothScroll in FOptions) and (r.Left <= clipr.Left) then + begin firstcol := col; - if r.Right >= clipr.Right then + if col>0 then inc (cLeft, cWidths[col-1]); + end; + if r.Left >= clipr.Right then break; inc (r.Left, r.Width); end; @@ -854,15 +861,17 @@ begin lastrow := firstrow; for row := firstrow to RowCount-1 do begin + lastrow := row; inc (r.Top, DefaultRowHeight); if r.Top >= clipr.Bottom then break; - lastrow := row; end; end; end; end; + PrepareCells (firstrow, lastrow, firstcol, lastcol); + r.Left := cLeft; r.Top := rTop; @@ -924,7 +933,7 @@ begin Include(drawstate, gdFocused); if (row = FFocusRow) and (col = FFocusCol) then Include(drawstate, gdSelected); - +writeln (row, 'x', col, ' l:', r.Left, ' w:', r.Width, ' t:', r.Top, ' h:', r.Height); if DoDrawCellEvent(row, col, r, drawstate) then DrawCell(row, col, r, drawstate); @@ -942,7 +951,7 @@ begin // break; end; end; // item drawing - +writeln; Canvas.SetClipRect(clipr); Canvas.SetColor(FBackgroundColor); @@ -1433,6 +1442,11 @@ begin UpdateScrollBars; end; +procedure TfpgBaseGrid.PrepareCells(firstrow, lastrow, firstcol, lastcol: integer); +begin + // for descendents +end; + constructor TfpgBaseGrid.Create(AOwner: TComponent); begin Updating; -- cgit v1.2.3-70-g09d2 From b7ef0bcec9f195dabda7a5908c2c9a6e4c2affec Mon Sep 17 00:00:00 2001 From: David Laurence Emerson Date: Thu, 18 Apr 2013 19:19:04 -0700 Subject: Grids: basegrid working great with PrepareCells function and new optimizations --- src/gui/fpg_basegrid.pas | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas index c8e93092..9b52a8ee 100644 --- a/src/gui/fpg_basegrid.pas +++ b/src/gui/fpg_basegrid.pas @@ -817,7 +817,7 @@ begin firstcol := FFirstCol; end; - // calculate column widths, and first/last columns and rows + // calculate column widths, and first/last columns if (ColumnCount <= 0) then begin firstcol := -1; @@ -830,17 +830,18 @@ begin for col := firstcol to ColumnCount-1 do begin cWidths[col] := ColumnWidth[col]; - r.Width := cWidths[firstcol]; - lastcol := 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; - if r.Left >= clipr.Right then + 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; @@ -858,14 +859,9 @@ begin else begin firstrow := FFirstRow; - lastrow := firstrow; - for row := firstrow to RowCount-1 do - begin - lastrow := row; - inc (r.Top, DefaultRowHeight); - if r.Top >= clipr.Bottom then - break; - end; + lastrow := firstrow + (clipr.Bottom - r.Top) div DefaultRowHeight; + if lastrow >= RowCount then + lastrow := RowCount-1; end; end; end; @@ -888,7 +884,7 @@ begin DrawHeader(col, r, 0); inc(r.Left, r.Width); //if r.Left >= clipr.Right then - // Break; // optimization made obsolete by firstcol/lastcol + // Break; // optimization made obsolete by lastcol end; inc(r.Top, r.Height); end; @@ -933,7 +929,6 @@ begin Include(drawstate, gdFocused); if (row = FFocusRow) and (col = FFocusCol) then Include(drawstate, gdSelected); -writeln (row, 'x', col, ' l:', r.Left, ' w:', r.Width, ' t:', r.Top, ' h:', r.Height); if DoDrawCellEvent(row, col, r, drawstate) then DrawCell(row, col, r, drawstate); @@ -943,15 +938,15 @@ writeln (row, 'x', col, ' l:', r.Left, ' w:', r.Width, ' t:', r.Top, ' h:', r.He inc(r.Left, r.Width); //if r.Left >= clipr.Right then - // Break; // small optimization. Don't draw what we can't see + // Break; // optimization made obsolete by lastcol end; // Inc(r.Top, FDefaultRowHeight+1); inc(r.Top, r.Height); //if r.Top >= clipr.Bottom then - // break; + // break; // optimization made obsolete by lastrow end; end; // item drawing -writeln; + Canvas.SetClipRect(clipr); Canvas.SetColor(FBackgroundColor); -- cgit v1.2.3-70-g09d2 From e6ec10df9b5a02dd61063627e8bb353d7ccd5f75 Mon Sep 17 00:00:00 2001 From: David Laurence Emerson Date: Thu, 18 Apr 2013 19:30:19 -0700 Subject: Grids: set horiz scrollbar pagesize to 5 for smoothscroll, 1 otherwise --- src/gui/fpg_basegrid.pas | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas index 9b52a8ee..3b0e445f 100644 --- a/src/gui/fpg_basegrid.pas +++ b/src/gui/fpg_basegrid.pas @@ -730,12 +730,14 @@ begin FHScrollBar.Max := cw - vw; FHScrollBar.Position := FXOffset; FHScrollBar.SliderSize := HWidth / TotalColumnWidth; + FHScrollBar.PageSize := 5; end else begin FHScrollBar.Max := ColumnCount-1; FHScrollBar.Position := FFirstCol; FHScrollBar.SliderSize := 1 / ColumnCount; + FHScrollBar.PageSize := 1; end; FHScrollBar.RepaintSlider; FHScrollBar.Top := Height -FHScrollBar.Height - 2; -- cgit v1.2.3-70-g09d2