1 #include "RichEdit.h"
2
3 namespace Upp {
4
5 #define IMAGECLASS RichEditImg
6 #define IMAGEFILE <RichEdit/RichEdit.iml>
7 #include <Draw/iml_source.h>
8
HotPaint(Draw & w,int x,int y,const Image & img)9 void HotPaint(Draw& w, int x, int y, const Image& img)
10 {
11 Point p = img.GetHotSpot();
12 w.DrawImage(x - p.x, y - p.y, img);
13 }
14
RichRuler()15 RichRuler::RichRuler() { newtabalign = ALIGN_LEFT; }
~RichRuler()16 RichRuler::~RichRuler() {}
17
FrameLayout(Rect & r)18 void RichRuler::FrameLayout(Rect& r)
19 {
20 LayoutFrameTop(r, this, Arial(Zy(10)).GetHeight() + Zy(8));
21 }
22
FrameAddSize(Size & sz)23 void RichRuler::FrameAddSize(Size& sz)
24 {
25 sz.cy += Arial(Zy(10)).GetHeight() + Zy(8);
26 }
27
Paint(Draw & w)28 void RichRuler::Paint(Draw& w)
29 {
30 Size sz = GetSize();
31 w.DrawRect(sz, SColorFace);
32 w.DrawRect(0, sz.cy - Zx(1), sz.cx, Zy(1), SColorShadow);
33 int cx = zoom * pgcx;
34 w.DrawRect(x0 - Zx(1), Zy(3), cx + Zx(3), sz.cy - Zy(6), SColorPaper);
35 int i = 0;
36 for(;;) {
37 int x = fround(++i * grid) * zoom;
38 if(x >= cx) break;
39 int h = (sz.cy - Zy(6)) / 3;
40 if(i % marks == 0)
41 w.DrawRect(x0 + x, Zy(2) + h, Zx(1), h + Zy(2), SColorHighlight);
42 else
43 w.DrawRect(x0 + x, Zy(3) + h, Zx(1), h, SColorHighlight);
44 }
45 i = 0;
46 int xs = 0;
47 for(;;)
48 if(++i % numbers == 0) {
49 int x = fround(i * grid) * zoom;
50 if(x >= cx) break;
51 String n = Format("%d", (int)(i * numbermul + 0.5));
52 Size tsz = GetTextSize(n, ArialZ(9));
53 int px = x0 + x - tsz.cx / 2;
54 if(px >= xs && x + tsz.cx - tsz.cx / 2 < cx) {
55 w.DrawRect(px, Zy(4), tsz.cx, sz.cy - Zy(8), SColorPaper);
56
57 w.DrawText(px, Zy(4) + (sz.cy - Zy(8) - tsz.cy) / 2,
58 n, ArialZ(9), SColorText);
59 xs = px + tsz.cx + Zx(4);
60 }
61 }
62 FieldFrame().FramePaint(w, RectC(x0 - Zx(1), Zy(3), cx + Zx(3), sz.cy - Zy(6)));
63 for(i = marker.GetCount() - 1; i >= 0; --i) {
64 const Marker& m = marker[i];
65 if(!IsNull(m.pos))
66 HotPaint(w, x0 + m.pos * zoom, m.top ? Zy(1) : sz.cy - Zy(4), DPI(m.image));
67 }
68 i = 0;
69 if(tabsize)
70 for(;;) {
71 int xp = ++i * tabsize;
72 int x = xp * zoom;
73 if(x >= cx) break;
74 if(xp > tabpos)
75 w.DrawRect(x0 + x, sz.cy - Zy(4), Zx(1), Zy(3), SColorShadow);
76 }
77 w.DrawImage(Zx(4), Zy(6), newtabalign == ALIGN_RIGHT ? RichEditImg::RightTab() :
78 newtabalign == ALIGN_CENTER ? RichEditImg::CenterTab() :
79 RichEditImg::LeftTab());
80 }
81
FindMarker(Point p)82 int RichRuler::FindMarker(Point p)
83 {
84 int x = p.x - x0;
85 bool top = p.y < GetSize().cy / 2;
86 for(int i = 0; i < marker.GetCount(); i++) {
87 const Marker& m = marker[i];
88 int hx = m.image.GetHotSpot().x;
89 int cx = m.image.GetSize().cx;
90 int p = zoom * m.pos;
91 if(m.top == top && x >= p - hx && x < p + cx - hx)
92 return i;
93 }
94 return -1;
95 }
96
LeftDown(Point p,dword)97 void RichRuler::LeftDown(Point p, dword)
98 {
99 track = FindMarker(p);
100 if(track >= 0) {
101 trackdx = marker[track].pos * zoom + x0 - p.x;
102 SetCapture();
103 WhenBeginTrack();
104 }
105 else
106 if(p.x < Zx(16)) {
107 newtabalign++;
108 if(newtabalign > ALIGN_CENTER) newtabalign = ALIGN_LEFT;
109 Refresh();
110 return;
111 }
112 else {
113 pos = ((p.x - x0) / zoom + snap / 2) / snap * snap;
114 WhenLeftDown();
115 }
116 }
117
LeftDouble(Point p,dword)118 void RichRuler::LeftDouble(Point p, dword)
119 {
120 if(p.x < x0 - Zx(3)) {
121 newtabalign++;
122 if(newtabalign > ALIGN_CENTER) newtabalign = ALIGN_LEFT;
123 Refresh();
124 return;
125 }
126
127 WhenLeftDouble();
128 }
129
RightDown(Point p,dword)130 void RichRuler::RightDown(Point p, dword)
131 {
132 if(p.x < x0 - Zx(3)) {
133 newtabalign--;
134 if(newtabalign < ALIGN_LEFT) newtabalign = ALIGN_CENTER;
135 Refresh();
136 return;
137 }
138
139 track = FindMarker(p);
140 if(track < 0)
141 pos = ((p.x - x0) / zoom + snap / 2) / snap * snap;
142 WhenRightDown();
143 }
144
LeftUp(Point p,dword)145 void RichRuler::LeftUp(Point p, dword)
146 {
147 track = -1;
148 WhenEndTrack();
149 }
150
MouseMove(Point p,dword flags)151 void RichRuler::MouseMove(Point p, dword flags)
152 {
153
154 if(HasCapture() && track >= 0) {
155 Marker& m = marker[track];
156 if((p.y < Zy(-10) || p.y >= GetSize().cy + Zy(10)) && m.deletable)
157 m.pos = Null;
158 else {
159 int x = ((p.x + trackdx - x0) / zoom);
160 if(!(flags & K_ALT))
161 x = (x + snap / 2) / snap * snap;
162 m.pos = minmax(x, m.minpos, m.maxpos);
163 }
164 Refresh();
165 WhenTrack();
166 }
167 }
168
SetLayout(int x,int _pgcx,Zoom _zoom,double _grid,int _numbers,double _numbermul,int _marks,int _snap)169 void RichRuler::SetLayout(int x, int _pgcx, Zoom _zoom,
170 double _grid, int _numbers, double _numbermul, int _marks, int _snap)
171 {
172 if(x0 != x || pgcx != _pgcx || zoom != _zoom || grid != _grid || numbers != _numbers ||
173 numbermul != _numbermul || marks != _marks || snap != _snap) {
174 x0 = x;
175 pgcx = _pgcx;
176 zoom = _zoom;
177 grid = _grid;
178 numbers = _numbers;
179 numbermul = _numbermul;
180 marks = _marks;
181 snap = _snap;
182 Refresh();
183 }
184 }
185
Clear()186 void RichRuler::Clear()
187 {
188 if(marker.GetCount()) {
189 marker.Clear();
190 Refresh();
191 }
192 }
193
SetCount(int n)194 void RichRuler::SetCount(int n)
195 {
196 if(marker.GetCount() != n) {
197 marker.SetCount(n);
198 Refresh();
199 }
200 }
201
Set(int i,const Marker & m)202 void RichRuler::Set(int i, const Marker& m)
203 {
204 if(i >= marker.GetCount() || marker[i] != m) {
205 marker.At(i) = m;
206 Refresh();
207 }
208 }
209
SetTabs(int pos,int size)210 void RichRuler::SetTabs(int pos, int size)
211 {
212 if(tabpos != pos || tabsize != size) {
213 tabpos = pos;
214 tabsize = size;
215 Refresh();
216 }
217 }
218
219 }
220