forked from HemulGM/ChatGPT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChatGPT.FramePlainText.pas
178 lines (156 loc) · 4.79 KB
/
ChatGPT.FramePlainText.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
unit ChatGPT.FramePlainText;
interface
{$IF DEFINED(ANDROID) OR DEFINED(IOS) OR DEFINED(IOS64)}
{$DEFINE MOBILE}
{$ENDIF}
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
FMX.Objects, FMX.Memo.Types, FMX.Controls.Presentation, FMX.ScrollBox,
FMX.Memo, FMX.Layouts, FMX.Memo.Style, ChatGPT.Classes, FMX.TextLayout,
ChatGPT.Code, FMX.RichEdit.Style;
type
TFrameText = class(TFrame)
MemoText: TMemo;
TimerMouseOver: TTimer;
procedure FrameResize(Sender: TObject);
procedure MemoTextMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
procedure MemoTextMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
procedure MemoTextMouseLeave(Sender: TObject);
procedure MemoTextClick(Sender: TObject);
procedure TimerMouseOverTimer(Sender: TObject);
procedure MemoTextPresentationNameChoosing(Sender: TObject;
var PresenterName: string);
private
FOnWheel: TMouseWheelEvent;
FStyledMemo: TRichEditStyled;
FMouseMemo: TPointF;
FUnderMouse: TUnderMouse;
FUnderMouseAttr: TTextAttribute;
procedure SetOnWheel(const Value: TMouseWheelEvent);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetContentHeight: Single;
procedure Fill(Data: TPart);
property OnWheel: TMouseWheelEvent read FOnWheel write SetOnWheel;
end;
implementation
uses
System.Math, System.Net.URLClient;
{$R *.fmx}
{ TFrameText }
constructor TFrameText.Create(AOwner: TComponent);
begin
inherited;
Name := '';
MemoText.DisableDisappear := True;
FUnderMouseAttr.Color := MemoText.TextSettings.FontColor; // $FF006CE8;
FUnderMouseAttr.Font := TFont.Create;
FUnderMouseAttr.Font.Assign(MemoText.TextSettings.Font);
FUnderMouseAttr.Font.Style := [TFontStyle.fsUnderline];
FStyledMemo := (MemoText.Presentation as TRichEditStyled);
{$IFDEF MOBILE}
MemoText.HitTest := False;
{$ENDIF}
MemoText.TextSettings.VertAlign := TTextAlign.Center;
end;
destructor TFrameText.Destroy;
begin
FUnderMouseAttr.Font.Free;
inherited;
end;
procedure TFrameText.Fill(Data: TPart);
begin
FStyledMemo.SetCodeSyntaxName('md', MemoText.Font, MemoText.FontColor);
MemoText.Text := Data.Content;
MemoText.TextSettings.WordWrap := True;
FrameResize(nil);
end;
procedure TFrameText.FrameResize(Sender: TObject);
begin
var H := GetContentHeight;
if H <> Height then
Height := H;
end;
function TFrameText.GetContentHeight: Single;
begin
FStyledMemo.RecalcSize;
var ContentH := MemoText.ContentBounds.Height;
if (ContentH + 5) < 30 then
MemoText.Margins.Top := 25 - ContentH
else
MemoText.Margins.Top := 0;
Result := Max(ContentH + 5, 30) +
MemoText.Margins.Top +
MemoText.Margins.Bottom;
end;
procedure TFrameText.MemoTextClick(Sender: TObject);
begin
if (FUnderMouse.WordLine <> -1) and (not FUnderMouse.Text.IsEmpty) and (MemoText.SelLength = 0) then
OpenUrl(FUnderMouse.Text);
end;
procedure TFrameText.MemoTextMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
begin
if (MemoText.SelLength > 0) and (Root.Captured = IControl(FStyledMemo)) then
begin
Handled := True;
if Assigned(FOnWheel) then
FOnWheel(Sender, Shift, WheelDelta, Handled);
end;
end;
procedure TFrameText.MemoTextPresentationNameChoosing(Sender: TObject;
var PresenterName: string);
begin
PresenterName := 'RichEditStyled';
end;
procedure TFrameText.SetOnWheel(const Value: TMouseWheelEvent);
begin
FOnWheel := Value;
end;
procedure TFrameText.MemoTextMouseLeave(Sender: TObject);
begin
{$IFDEF NEW_MEMO}
TimerMouseOver.Enabled := False;
FUnderMouse.WordLine := -1;
FStyledMemo.UpdateVisibleLayoutParams;
FStyledMemo.Repaint;
{$ENDIF}
end;
procedure TFrameText.MemoTextMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
begin
{$IFDEF NEW_MEMO}
TimerMouseOver.Enabled := False;
TimerMouseOver.Enabled := True;
FMouseMemo := TPointF.Create(X, Y);
{$ENDIF}
end;
procedure TFrameText.TimerMouseOverTimer(Sender: TObject);
begin
TimerMouseOver.Enabled := False;
{$IFDEF NEW_MEMO} {
var BeginWord: Int64;
var Line: Int64;
var Str := FStyledMemo.GetWordAtPos(FMouseMemo.X, FMouseMemo.Y, BeginWord, Line);
if (not Str.IsEmpty) and (Str.ToLower.StartsWith('http')) then
try
TURI.Create(Str);
MemoText.Cursor := crHandPoint;
except
MemoText.Cursor := crDefault;
Line := -1;
end
else
begin
MemoText.Cursor := crDefault;
Line := -1;
end;
FUnderMouse.WordStart := BeginWord;
FUnderMouse.WordLength := Str.Length;
FUnderMouse.WordLine := Line;
FUnderMouse.Text := Str;
FStyledMemo.UpdateVisibleLayoutParams;
MemoText.Repaint; }
{$ENDIF}
end;
end.