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