karbon

vruler.cpp
1/*
2 * Kivio - Visual Modelling and Flowcharting
3 * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
4 * Copyright (C) 2002 Patrick Julien <freak@codepimps.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20#include <tqpainter.h>
21
22#include "kdebug.h"
23
24#include "vruler.h"
25
26#define MARKER_WIDTH 1
27#define MARKER_HEIGHT 20
28#define RULER_SIZE 20
29
30const char *VRuler::m_nums[] = {
31 "70 7 2 1",
32 " c Black",
33 "X c None",
34 "XX XXXXXX XXXX XXXX XXXXXX XXX XXXX XXX XXX XXXX XX",
35 "X XXX XXXX XXX XXX XX XXX XXXX XXX XXXXXXX XXXXXXXXX XX XXX XX XXX X",
36 "X XXX XXXXX XXXXXXX XXXXXX XXX X XXX XXXXXX XXXXXXXXX XXX XXX XX XXX X",
37 "X XXX XXXXX XXXXX XXXXX XXX XX XXX XXX XXXXXX XXXX XXXX X",
38 "X XXX XXXXX XXXX XXXXXXXXX XX XXXXXX XX XXX XXXX XXXX XXX XXXXXX X",
39 "X XXX XXXXX XXX XXXXXX XXX XXXXX XXXXXXX XX XXX XXXX XXXX XXX XXXXX XX",
40 "XX XXXXXX XXX XXX XXXXXX XXX XXXX XXXXX XXXXX XXXX XXX"
41};
42
43VRuler::VRuler(TQt::Orientation o, TQWidget *parent, const char *name) : super(parent, name, WRepaintNoErase | WResizeNoErase), m_pixmapNums(m_nums)
44{
45 setBackgroundMode(NoBackground);
46 setFrameStyle(Box | Sunken);
47 setLineWidth(1);
48 setMidLineWidth(0);
49 m_orientation = o;
50 m_unit = KoUnit::U_PT;
51 m_zoom = 1.0;
52 m_firstVisible = 0;
53 m_pixmapBuffer = 0;
54 m_currentPosition = -1;
55
56 if (m_orientation == TQt::Horizontal) {
57 setFixedHeight(RULER_SIZE);
58 initMarker(MARKER_WIDTH, MARKER_HEIGHT);
59 } else {
60 setFixedWidth(RULER_SIZE);
61 initMarker(MARKER_HEIGHT, MARKER_WIDTH);
62 }
63}
64
65VRuler::~VRuler()
66{
67 delete m_pixmapBuffer;
68}
69
70void VRuler::initMarker(TQ_INT32 w, TQ_INT32 h)
71{
72 TQPainter p;
73
74 m_pixmapMarker.resize(w, h);
75 p.begin(&m_pixmapMarker);
76 p.setPen(blue);
77 p.eraseRect(0, 0, w, h);
78 p.drawLine(0, 0, w - 1, h - 1);
79 p.end();
80}
81
82void VRuler::recalculateSize()
83{
84 TQ_INT32 w;
85 TQ_INT32 h;
86
87 if (m_pixmapBuffer) {
88 delete m_pixmapBuffer;
89 m_pixmapBuffer = 0;
90 }
91
92 if (m_orientation == TQt::Horizontal) {
93 w = width();
94 h = RULER_SIZE;
95 } else {
96 w = RULER_SIZE;
97 h = height();
98 }
99
100 m_pixmapBuffer = new TQPixmap(w, h);
101 TQ_CHECK_PTR(m_pixmapBuffer);
102
103 drawRuler();
104 updatePointer(m_currentPosition, m_currentPosition);
105}
106
107KoUnit::Unit VRuler::unit() const
108{
109 return m_unit;
110}
111
112void VRuler::setUnit(KoUnit::Unit u)
113{
114 m_unit = u;
115 drawRuler();
116 updatePointer(m_currentPosition, m_currentPosition);
117 repaint();
118}
119
120void VRuler::setZoom(double zoom)
121{
122 m_zoom = zoom;
123 recalculateSize();
124 drawRuler();
125 updatePointer(m_currentPosition, m_currentPosition);
126 repaint();
127}
128
129void VRuler::updatePointer(TQ_INT32 x, TQ_INT32 y)
130{
131 if (m_pixmapBuffer) {
132 if (m_orientation == TQt::Horizontal) {
133 if (m_currentPosition != -1)
134 repaint(m_currentPosition, 1, MARKER_WIDTH, MARKER_HEIGHT);
135
136 if (x != -1) {
137 bitBlt(this, x, 1, &m_pixmapMarker, 0, 0, MARKER_WIDTH, MARKER_HEIGHT);
138 m_currentPosition = x;
139 }
140 } else {
141 if (m_currentPosition != -1)
142 repaint(1, m_currentPosition, MARKER_HEIGHT, MARKER_WIDTH);
143
144 if (y != -1) {
145 bitBlt(this, 1, y, &m_pixmapMarker, 0, 0, MARKER_HEIGHT, MARKER_WIDTH);
146 m_currentPosition = y;
147 }
148 }
149 }
150}
151
152void VRuler::updateVisibleArea(TQ_INT32 xpos, TQ_INT32 ypos)
153{
154 if (m_orientation == TQt::Horizontal)
155 m_firstVisible = xpos;
156 else
157 m_firstVisible = ypos;
158
159 //kdDebug() << "--###-- VRuler::updateVisibleArea(" << xpos << ", " << ypos << ")" << endl;
160 drawRuler();
161 repaint();
162 updatePointer(m_currentPosition, m_currentPosition);
163 //kdDebug() << "--###-- VRuler::updatePointer(" << m_currentPosition << ", " << m_currentPosition << ")" << endl;
164}
165
166void VRuler::paintEvent(TQPaintEvent *e)
167{
168 if (m_pixmapBuffer) {
169 const TQRect& rect = e -> rect();
170
171 bitBlt(this, rect.topLeft(), m_pixmapBuffer, rect);
172 super::paintEvent(e);
173 }
174}
175
176void VRuler::drawRuler()
177{
178 TQPainter p;
179 TQString buf;
180 TQ_INT32 st1 = 0;
181 TQ_INT32 st2 = 0;
182 TQ_INT32 st3 = 0;
183 TQ_INT32 st4 = 0;
184 TQ_INT32 stt = 0;
185
186 if (!m_pixmapBuffer)
187 return;
188
189 p.begin(m_pixmapBuffer);
190 p.setPen(TQColor(0x70, 0x70, 0x70));
191 p.setBackgroundColor(colorGroup().background());
192 p.eraseRect(0, 0, m_pixmapBuffer -> width(), m_pixmapBuffer -> height());
193
194 switch (m_unit) {
195 case KoUnit::U_PT:
196 case KoUnit::U_MM:
197 case KoUnit::U_DD:
198 case KoUnit::U_CC:
199 st1 = 1;
200 st2 = 5;
201 st3 = 10;
202 st4 = 25;
203 stt = 100;
204 break;
205 case KoUnit::U_CM:
206 case KoUnit::U_PI:
207 case KoUnit::U_INCH:
208 st1 = 1;
209 st2 = 2;
210 st3 = 5;
211 st4 = 10;
212 stt = 1;
213 break;
214 default:
215 break;
216 }
217
218 TQ_INT32 pos = 0;
219 bool s1 = KoUnit::fromUserValue(st1, m_unit) * m_zoom > 3.0;
220 bool s2 = KoUnit::fromUserValue(st2, m_unit) * m_zoom > 3.0;
221 bool s3 = KoUnit::fromUserValue(st3, m_unit) * m_zoom > 3.0;
222 bool s4 = KoUnit::fromUserValue(st4, m_unit) * m_zoom > 3.0;
223
224 if (m_orientation == TQt::Horizontal) {
225 // XXX: This was 7 * 4 -- why? what was the idea about having 30 point intervals?
226 float cx = KoUnit::fromUserValue(100, m_unit) / m_zoom;
227 TQ_INT32 step = tqRound(cx);//((TQ_INT32)(cx / (float)stt) + 1) * stt;
228 TQ_INT32 start = (TQ_INT32)(KoUnit::toUserValue(m_firstVisible, m_unit) / m_zoom);
229
230 do {
231 pos = (TQ_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible);
232
233 if (!s3 && s4 && start % st4 == 0)
234 p.drawLine(pos, RULER_SIZE - 9, pos, RULER_SIZE);
235
236 if (s3 && start % st3 == 0)
237 p.drawLine(pos, RULER_SIZE - 9, pos, RULER_SIZE);
238
239 if (s2 && start % st2 == 0)
240 p.drawLine(pos, RULER_SIZE - 7, pos, RULER_SIZE);
241
242 if (s1 && start % st1 == 0)
243 p.drawLine(pos, RULER_SIZE - 5, pos, RULER_SIZE);
244
245 if (step && start % step == 0) {
246 buf.setNum(TQABS(start));
247 drawNums(&p, pos, 4, buf, true);
248 }
249
250 start++;
251 } while (pos < m_pixmapBuffer -> width());
252 } else {
253 m_firstVisible = 0;
254 float cx = KoUnit::fromUserValue(100, m_unit) / m_zoom;
255 TQ_INT32 height = m_pixmapBuffer -> height() - 1;
256 TQ_INT32 step = tqRound(cx);
257 TQ_INT32 start = (TQ_INT32)(KoUnit::toUserValue(m_firstVisible, m_unit) / m_zoom);
258
259 do {
260 pos = height - (TQ_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible);
261
262 if (!s3 && s4 && start % st4 == 0)
263 p.drawLine(RULER_SIZE - 9, pos, RULER_SIZE, pos);
264
265 if (s3 && start % st3 == 0)
266 p.drawLine(RULER_SIZE - 9, pos, RULER_SIZE, pos);
267
268 if (s2 && start % st2 == 0)
269 p.drawLine(RULER_SIZE - 7, pos, RULER_SIZE, pos);
270
271 if (s1 && start % st1 == 0)
272 p.drawLine(RULER_SIZE - 5, pos, RULER_SIZE, pos);
273
274 if (step && start % step == 0) {
275 buf.setNum(TQABS(start));
276 drawNums(&p, 4, pos, buf, false);
277 }
278
279 start++;
280 } while (pos > 0);
281 }
282
283 p.end();
284}
285
286void VRuler::resizeEvent(TQResizeEvent *)
287{
288 recalculateSize();
289}
290
291void VRuler::show()
292{
293 if (m_orientation == TQt::Horizontal) {
294 setFixedHeight(RULER_SIZE);
295 initMarker(MARKER_WIDTH, MARKER_HEIGHT);
296 } else {
297 setFixedWidth(RULER_SIZE);
298 initMarker(MARKER_HEIGHT, MARKER_WIDTH);
299 }
300
301 super::show();
302}
303
304void VRuler::hide()
305{
306 if (m_orientation == TQt::Horizontal)
307 setFixedHeight(1);
308 else
309 setFixedWidth(1);
310}
311
312void VRuler::drawNums(TQPainter *p, TQ_INT32 x, TQ_INT32 y, TQString& num, bool orientationHoriz)
313{
314 if (orientationHoriz)
315 x -= 7;
316 else
317 y -= 8;
318
319 for (TQ_UINT32 k = 0; k < num.length(); k++) {
320 TQ_INT32 st = num.at(k).digitValue() * 7;
321
322 p -> drawPixmap(x, y, m_pixmapNums, st, 0, 7, 7);
323
324 if (orientationHoriz)
325 x += 7;
326 else
327 y += 8;
328 }
329}
330
331#include "vruler.moc"
332