How to make a particular line to topmost?
How to make a particular line to topmost?
How can I make the line where the cursor is, to the topmost of a TRichViewEdit?
Last edited by donwynne on Mon Mar 28, 2022 6:33 am, edited 2 times in total.
Re: How to make a particular line to topmost?
I tried this and it seems to work:
Code: Select all
procedure ScrollItemToTop(rve: TCustomRichViewEdit);
var
DItem, DOffs: integer;
begin
rve.RVData.Item2DrawItem(rve.CurItemNo, rve.OffsetInCurItem, DItem, DOffs );
rve.ScrollToDrawItem( rve.RVData, DItem, false, false );
rve.SetFocusSilent;
end;
-
- Site Admin
- Posts: 17565
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: How to make a particular line to topmost?
Yes, this is almost a correct solution. To support caret in table cells:
It has two small problems:
- it scrolls to the top of the item containing the caret, not to the top of the line (the difference is noticeable if the line has items that are taller than this item
- if a line is wrapped, and not on a space character, the position at the end of this line and at the beginning of the next line has the same (rve.CurItemNo, rve.OffsetInCurItem).
These problems are small, so you can use this solution.
A perfect solution requires undocumented methods, see my next post.
Code: Select all
procedure ScrollItemToTop(rve: TCustomRichViewEdit);
var
DItem, DOffs: integer;
tle: TCustomRichViewEdit;
begin
tle := rve.TopLevelEditor;
tle.RVData.Item2DrawItem(tle.CurItemNo, tle.OffsetInCurItem, DItem, DOffs );
rve.ScrollToDrawItem( tle.RVData, DItem, false, false );
rve.SetFocusSilent;
end;
It has two small problems:
- it scrolls to the top of the item containing the caret, not to the top of the line (the difference is noticeable if the line has items that are taller than this item
- if a line is wrapped, and not on a space character, the position at the end of this line and at the beginning of the next line has the same (rve.CurItemNo, rve.OffsetInCurItem).
These problems are small, so you can use this solution.
A perfect solution requires undocumented methods, see my next post.
-
- Site Admin
- Posts: 17565
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: How to make a particular line to topmost?
How to scroll to the top of the current line.
How to call:
Code: Select all
uses CRVFData, RVERVData, DLines, RVCoords;
// Returns a range of drawing items on the RVData's line containing
// the DItemNo-th drawing item
procedure GetDItemsInLine(RVData: TCustomRVFormattedData;
DItemNo: Integer; out DItemNo1, DItemNo2: Integer);
begin
DItemNo1 := DItemNo;
while not RVData.DrawItems[DItemNo1].FromNewLine do
dec(DItemNo1);
DItemNo2 := DItemNo + 1;
while (DItemNo2 < RVData.DrawItems.Count) and
not RVData.DrawItems[DItemNo2].FromNewLine do
inc(DItemNo2);
dec(DItemNo2);
end;
// Returns the top coordinate of the RVData's line containing
// the DItemNo-th drawing item, relative to the top corner of the rv's document.
function GetLineTop(rv: TCustomRichView; RVData: TCustomRVFormattedData;
DItemNo: Integer): TRVCoord;
var
i, DItemNo1, DItemNo2: Integer;
R: TRVCoordRect;
function GetDrawItemCoords(Index: Integer): TRVCoordRect;
var
DItem: TRVDrawLineInfo;
begin
DItem := RVData.DrawItems[Index];
Result := RVCoordBounds(DItem.Left, RVData.GetTransformedDItemTop(Index),
DItem.Width, DItem.Height);
end;
begin
GetDItemsInLine(RVData, DItemNo, DItemNo1, DItemNo2);
R := GetDrawItemCoords(DItemNo);
for i := DItemNo1 + 1 to DItemNo2 do
UnionRect(R, R, GetDrawItemCoords(i));
RVData.RotateRectFromDocToScreen(R, rvtrbAbsRoot);
Result := R.Top;
end;
Code: Select all
var
Y: TRVCoord;
begin
Y := GetLineTop(RichViewEdit1, RichViewEdit1.TopLevelEditor.RVData,
TRVEditRVData(RichViewEdit1.TopLevelEditor.RVData).CaretDrawItemNo);
RichViewEdit1.ScrollTo(Y);
end;
-
- Site Admin
- Posts: 17565
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: How to make a particular line to topmost?
Your code can be modified to avoid this problem:if a line is wrapped, and not on a space character, the position at the end of this line and at the beginning of the next line has the same (rve.CurItemNo, rve.OffsetInCurItem).
Code: Select all
uses RVERVData;
procedure ScrollItemToTop(rve: TCustomRichViewEdit);
var
DItem: integer;
tle: TCustomRichViewEdit;
begin
tle := rve.TopLevelEditor;
DItem := TRVEditRVData(tle.RVData).CaretDrawItemNo;
rve.ScrollToDrawItem( tle.RVData, DItem, false, false );
rve.SetFocusSilent;
end;
Re: How to make a particular line to topmost?
I had forgotten about tables again. I'm not implementing them as such in my app but I do like to account for them in case I copy and paste one or more tables into my rve.
I hadn't gotten quite as far as using CaretDrawItemNo but yes, that's the better way! I would have probably gotten to that eventually.
I wasn't the original poster for this but I'd been wanting to figure it out at some point so seeing this got me thinking about it again.
Thanks Sergey, great info.
I hadn't gotten quite as far as using CaretDrawItemNo but yes, that's the better way! I would have probably gotten to that eventually.
I wasn't the original poster for this but I'd been wanting to figure it out at some point so seeing this got me thinking about it again.
Thanks Sergey, great info.