centering selected text by scrolling
-
- Posts: 13
- Joined: Fri Feb 04, 2011 12:05 am
centering selected text by scrolling
Hi.
I'm trying to center the selected text in ScaleRichView but I can't find a function for this.
I mean by scrolling the text in fewest steps possible.
I tried ScrollToCaret and ScrollToItem but they only bring the selected text in the view, they're not placing it in the middle (vertically and even horizontally if possible).
Can anyone please help me make such a function..?
I'm asking for help because I'm new in using ScaleRichView and I only know basic functions not complex ones required for this function to work properly...
Thank you very much for any help.
I'm trying to center the selected text in ScaleRichView but I can't find a function for this.
I mean by scrolling the text in fewest steps possible.
I tried ScrollToCaret and ScrollToItem but they only bring the selected text in the view, they're not placing it in the middle (vertically and even horizontally if possible).
Can anyone please help me make such a function..?
I'm asking for help because I'm new in using ScaleRichView and I only know basic functions not complex ones required for this function to work properly...
Thank you very much for any help.
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
This code shows the selected text in the middle (only vertically).
(if selection is longer than the editor height, it scrolls to the beginning of this selection).
This code uses undocumented functions.
(if selection is longer than the editor height, it scrolls to the beginning of this selection).
This code uses undocumented functions.
Code: Select all
uses DLines, CRVFData;
var
RVData: TCustomRVFormattedData;
SItemNo, SItemOffs, EItemNo, EItemOffs,
SDItemNo, SDItemOffs, EDItemNo, EDItemOffs, i, Step,
Top, Bottom, X, Y: Integer;
begin
// finding range of selected "drawing items"
RVData := SRichViewEdit1.RichViewEdit.TopLevelEditor.RVData;
RVData.GetSelectionBoundsEx(SItemNo, SItemOffs, EItemNo, EItemOffs, True);
RVData.Item2DrawItem(SItemNo, SItemOffs, SDItemNo, SDItemOffs);
RVData.Item2DrawItem(EItemNo, EItemOffs, EDItemNo, EDItemOffs);
// calculating Top and Bottom in coordinates of RVData
Top := RVData.DrawItems[SDItemNo].Top;
Bottom := RVData.DrawItems[SDItemNo].Top+RVData.DrawItems[SDItemNo].Height;
for i := SDItemNo+1 to EDItemNo do begin
if Top>RVData.DrawItems[i].Top then
Top := RVData.DrawItems[i].Top;
if Bottom<RVData.DrawItems[i].Top+RVData.DrawItems[i].Height then
Bottom := RVData.DrawItems[i].Top+RVData.DrawItems[i].Height;
end;
// converting to coordinates of SRichViewEdit1.RichViewEdit
RVData.GetOriginEx(X, Y);
inc(Top, Y);
inc(Bottom, Y);
// converting to coordinates of SRichViewEdit1
Step := SRichViewEdit1.RichViewEdit.VSmallStep;
[color=blue] dec(Top, SRichViewEdit1.RichViewEdit.VScrollPos*Step);
dec(Bottom, SRichViewEdit1.RichViewEdit.VScrollPos*Step);[/color]
Top := SRichViewEdit1.ConvertRVtoSRV(Point(0,Top)).Y+SRichViewEdit1.VScrollPos*Step;
Bottom := SRichViewEdit1.ConvertRVtoSRV(Point(0,Bottom)).Y+SRichViewEdit1.VScrollPos*Step;
// scrolling
if Bottom-Top>SRichViewEdit1.ClientHeight then
SRichViewEdit1.VScrollPos := Top div Step
else
SRichViewEdit1.VScrollPos := (Top+Bottom-SRichViewEdit1.ClientHeight) div (Step*2);
end;
Last edited by Sergey Tkachenko on Thu Feb 17, 2011 2:46 pm, edited 1 time in total.
-
- Posts: 13
- Joined: Fri Feb 04, 2011 12:05 am
Thank you very much.
A friend of mine gave me this code:
But I think your code is better because it takes also the height of the selection into account.
A friend of mine gave me this code:
Code: Select all
SRichViewEdit1.VScrollPos := ((Round(SRichViewEdit1.CaretPos.Y - SRichViewEdit1.OffsetY) - (SRichViewEdit1.ClientHeight div 2)) div SRichViewEdit1.RichViewEdit.VSmallStep) - 1;
-
- Posts: 13
- Joined: Fri Feb 04, 2011 12:05 am
By the way, how can you calculate the height of the item from the position of the caret?
I tried to show a window below the text:
GetWindowRect(SRichViewEdit1.Handle, r);
Window.Top := r.Top + SRichViewEdit1.CaretPos.Y + RVData.DrawItems[SRichViewEdit1.RichViewEdit.CurItemNo].Height;
But it was inside the item.
Later edit:
This code seems to work:
GetWindowRect(SRichViewEdit1.Handle, r);
Window.Top := r.Top + SRichViewEdit1.CaretPos.Y + Round(1.3 * SRichViewEdit1.RichViewEdit.RVData.DrawItems[SRichViewEdit1.RichViewEdit.CurItemNo].Height * SRichViewEdit1.ViewProperty.ZoomPercent / 100);
But I'm not so sure that it's 100% fine...
I tried to show a window below the text:
GetWindowRect(SRichViewEdit1.Handle, r);
Window.Top := r.Top + SRichViewEdit1.CaretPos.Y + RVData.DrawItems[SRichViewEdit1.RichViewEdit.CurItemNo].Height;
But it was inside the item.
Later edit:
This code seems to work:
GetWindowRect(SRichViewEdit1.Handle, r);
Window.Top := r.Top + SRichViewEdit1.CaretPos.Y + Round(1.3 * SRichViewEdit1.RichViewEdit.RVData.DrawItems[SRichViewEdit1.RichViewEdit.CurItemNo].Height * SRichViewEdit1.ViewProperty.ZoomPercent / 100);
But I'm not so sure that it's 100% fine...
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
This code shows the popup menu of the bottom right corner of the item [part] containing the caret:
Code: Select all
var rve: TCustomRichViewEdit;
ItemNo, Part: Integer;
ItemR, PageR: TRect;
P: TPoint;
begin
rve := SRichViewEdit1.RichViewEdit.TopLevelEditor;
ItemNo := rve.CurItemNo;
Part :=rve.RVData.GetItemPart(ItemNo, rve.OffsetInCurItem);
ItemR := SRichViewEdit1.GetItemBounds(rve.RVData, ItemNo, Part);
PageR := SRichViewEdit1.GetPageClientRect(SRichViewEdit1.CurrentPage);
P := SRichViewEdit1.ClientToScreen(
Point(PageR.Left+ItemR.Right, PageR.Top+ItemR.Bottom));
PopupMenu1.Popup(P.x, P.y);
end;
-
- Posts: 13
- Joined: Fri Feb 04, 2011 12:05 am
Thank you.
I used your code to also popup the context menu at caret position when the user presses "windows context menu" key:
It works fine when the menu pops up at the bottom (downwards) but not when it pops up at the top (upwards). It covers the item. In this case "+ ItemR.Top" should be used instead of "+ ItemR.Bottom".
But I don't know a good way to find the direction in advance. And I see that Word has the same problem...
I used your code to also popup the context menu at caret position when the user presses "windows context menu" key:
Code: Select all
procedure TForm1.SRichViewEdit1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
var P: TPoint;
Part: Integer;
ItemR, PageR: TRect;
begin
if (Key = 93) and (Shift = []) then
with Sender as TSRichViewEdit do
begin
Part := RichViewEdit.TopLevelEditor.RVData.GetItemPart(RichViewEdit.TopLevelEditor.CurItemNo, RichViewEdit.TopLevelEditor.OffsetInCurItem);
ItemR := GetItemBounds(RichViewEdit.TopLevelEditor.RVData, RichViewEdit.TopLevelEditor.CurItemNo, Part);
PageR := GetPageClientRect(CurrentPage);
P := ClientToScreen(Point(CaretPos.X, PageR.Top + ItemR.Bottom));
RVAPopupMenu1.Popup(P.X, P.Y);
end;
end;
But I don't know a good way to find the direction in advance. And I see that Word has the same problem...
-
- Posts: 13
- Joined: Fri Feb 04, 2011 12:05 am
Problem.
I found some big rtf's on which the centering function doesn't work well. It goes down dozens of pages after the location.
I tried in ActionTest too, no change.
The code from my friend works fine...
For example on this rtf: http://www.mediafire.com/download.php?g7fzq8qk1eqwhq2
I found some big rtf's on which the centering function doesn't work well. It goes down dozens of pages after the location.
I tried in ActionTest too, no change.
The code from my friend works fine...
For example on this rtf: http://www.mediafire.com/download.php?g7fzq8qk1eqwhq2
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
-
- Posts: 13
- Joined: Fri Feb 04, 2011 12:05 am
-
- Posts: 13
- Joined: Fri Feb 04, 2011 12:05 am
Hi.
I've been using this code for some time and I noticed a problem with some texts and some particular settings in Page setup.
I am able to reproduce the problem in ActionTest: http://www.mediafire.com/download.php?foy9j2tah06hpdh
Just click on Button2 and after that 2 times on Ok.
You'll get this:
When the caret is at the first line from the page (the second image) it returns value for ItemR like the position of the caret is measured with an additional hole page.
Is there something that can be done..?
Thank you.
I've been using this code for some time and I noticed a problem with some texts and some particular settings in Page setup.
I am able to reproduce the problem in ActionTest: http://www.mediafire.com/download.php?foy9j2tah06hpdh
Just click on Button2 and after that 2 times on Ok.
You'll get this:
When the caret is at the first line from the page (the second image) it returns value for ItemR like the position of the caret is measured with an additional hole page.
Is there something that can be done..?
Thank you.
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact: