chalk

kis_ruler.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#include <tqstyle.h>
22
23#include "kdebug.h"
24
25#include "kis_ruler.h"
26
27#define MARKER_WIDTH 1
28#define MARKER_HEIGHT RULER_THICKNESS
29
30const char *KisRuler::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
43KisRuler::KisRuler(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_THICKNESS);
58 initMarker(MARKER_WIDTH, MARKER_HEIGHT);
59 } else {
60 setFixedWidth(RULER_THICKNESS);
61 initMarker(MARKER_HEIGHT, MARKER_WIDTH);
62 }
63}
64
65KisRuler::~KisRuler()
66{
67 delete m_pixmapBuffer;
68}
69
70void KisRuler::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 KisRuler::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_THICKNESS;
95 } else {
96 w = RULER_THICKNESS;
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 KisRuler::unit() const
108{
109 return m_unit;
110}
111
112void KisRuler::setUnit(KoUnit::Unit u)
113{
114 m_unit = u;
115 drawRuler();
116 updatePointer(m_currentPosition, m_currentPosition);
117 update();
118}
119
120void KisRuler::setZoom(double zoom)
121{
122 m_zoom = zoom;
123 recalculateSize();
124 drawRuler();
125 updatePointer(m_currentPosition, m_currentPosition);
126 update();
127}
128
129void KisRuler::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 KisRuler::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 drawRuler();
160 update();
161 updatePointer(m_currentPosition, m_currentPosition);
162}
163
164void KisRuler::paintEvent(TQPaintEvent *e)
165{
166 if (m_pixmapBuffer) {
167 const TQRect& rect = e->rect();
168
169 bitBlt(this, rect.topLeft(), m_pixmapBuffer, rect);
170 super::paintEvent(e);
171 }
172}
173
174void KisRuler::drawRuler()
175{
176 TQPainter p;
177 TQString buf;
178 TQ_INT32 st1 = 0;
179 TQ_INT32 st2 = 0;
180 TQ_INT32 st3 = 0;
181 TQ_INT32 st4 = 0;
182
183 if (!m_pixmapBuffer)
184 return;
185
186 p.begin(m_pixmapBuffer);
187 p.setPen(colorGroup().text());
188 p.setBackgroundColor(colorGroup().base());
189 p.eraseRect(0, 0, m_pixmapBuffer->width(), m_pixmapBuffer->height());
190
191 switch (m_unit) {
192 case KoUnit::U_PT:
193 case KoUnit::U_MM:
194 case KoUnit::U_DD:
195 case KoUnit::U_CC:
196 st1 = 1;
197 st2 = 5;
198 st3 = 10;
199 st4 = 25;
200 break;
201 case KoUnit::U_CM:
202 case KoUnit::U_PI:
203 case KoUnit::U_INCH:
204 default:
205 st1 = 1;
206 st2 = 2;
207 st3 = 5;
208 st4 = 10;
209 }
210
211 bool s1 = KoUnit::fromUserValue(st1, m_unit) * m_zoom > 3.0;
212 bool s2 = KoUnit::fromUserValue(st2, m_unit) * m_zoom > 3.0;
213 bool s3 = KoUnit::fromUserValue(st3, m_unit) * m_zoom > 3.0;
214 bool s4 = KoUnit::fromUserValue(st4, m_unit) * m_zoom > 3.0;
215
216 float cx = KoUnit::fromUserValue(100, m_unit) / m_zoom;
217 TQ_INT32 step = tqRound(cx);
218
219 if (step < 5) {
220 step = 1;
221 } else if (step < 10) {
222 step = 5;
223 } else if (step < 25) {
224 step = 10;
225 } else if (step < 50) {
226 step = 25;
227 } else if (step < 100) {
228 step = 50;
229 } else if (step < 250) {
230 step = 100;
231 } else if (step < 500) {
232 step = 250;
233 } else if (step < 1000) {
234 step = 500;
235 } else if (step < 2500) {
236 step = 1000;
237 } else if (step < 5000) {
238 step = 2500;
239 } else if (step < 10000) {
240 step = 5000;
241 } else if (step < 25000) {
242 step = 10000;
243 } else if (step < 50000) {
244 step = 25000;
245 } else if (step < 100000) {
246 step = 50000;
247 } else {
248 step = 100000;
249 }
250
251 TQ_INT32 start = (TQ_INT32)(KoUnit::fromUserValue(m_firstVisible, m_unit) / m_zoom);
252 TQ_INT32 pos = 0;
253
254 if (m_orientation == TQt::Horizontal) {
255 do {
256 pos = (TQ_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible);
257
258 if (!s3 && s4 && start % st4 == 0)
259 p.drawLine(pos, RULER_THICKNESS - 9, pos, RULER_THICKNESS);
260
261 if (s3 && start % st3 == 0)
262 p.drawLine(pos, RULER_THICKNESS - 9, pos, RULER_THICKNESS);
263
264 if (s2 && start % st2 == 0)
265 p.drawLine(pos, RULER_THICKNESS - 7, pos, RULER_THICKNESS);
266
267 if (s1 && start % st1 == 0)
268 p.drawLine(pos, RULER_THICKNESS - 5, pos, RULER_THICKNESS);
269
270 if (start % step == 0) {
271 buf.setNum(TQABS(start));
272 drawNums(&p, pos, 4, buf, true);
273 }
274
275 start++;
276 } while (pos < m_pixmapBuffer->width());
277 } else {
278 do {
279 pos = (TQ_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible);
280
281 if (!s3 && s4 && start % st4 == 0)
282 p.drawLine(RULER_THICKNESS - 9, pos, RULER_THICKNESS, pos);
283
284 if (s3 && start % st3 == 0)
285 p.drawLine(RULER_THICKNESS - 9, pos, RULER_THICKNESS, pos);
286
287 if (s2 && start % st2 == 0)
288 p.drawLine(RULER_THICKNESS - 7, pos, RULER_THICKNESS, pos);
289
290 if (s1 && start % st1 == 0)
291 p.drawLine(RULER_THICKNESS - 5, pos, RULER_THICKNESS, pos);
292
293 if (start % step == 0) {
294 buf.setNum(TQABS(start));
295 drawNums(&p, 4, pos, buf, false);
296 }
297
298 start++;
299 } while (pos < m_pixmapBuffer->height());
300 }
301
302 p.end();
303}
304
305void KisRuler::resizeEvent(TQResizeEvent *)
306{
307 recalculateSize();
308}
309
310void KisRuler::styleChange(TQStyle& oldStyle)
311{
312 Q_UNUSED(oldStyle);
313 updateGeometry();
314 drawRuler();
315}
316
317void KisRuler::paletteChange(const TQPalette& oldPalette)
318{
319 Q_UNUSED(oldPalette);
320 drawRuler();
321}
322
323void KisRuler::show()
324{
325 if (m_orientation == TQt::Horizontal) {
326 setFixedHeight(RULER_THICKNESS);
327 initMarker(MARKER_WIDTH, MARKER_HEIGHT);
328 } else {
329 setFixedWidth(RULER_THICKNESS);
330 initMarker(MARKER_HEIGHT, MARKER_WIDTH);
331 }
332
333 super::show();
334}
335
336void KisRuler::hide()
337{
338 /*
339 if (m_orientation == TQt::Horizontal)
340 setFixedHeight(1);
341 else
342 setFixedWidth(1);
343 */
344 super::hide();
345}
346
347void KisRuler::drawNums(TQPainter *p, TQ_INT32 x, TQ_INT32 y, TQString& num, bool orientationHoriz)
348{
349 if (orientationHoriz)
350 x -= 7;
351 else
352 y -= 8;
353
354 for (TQ_UINT32 k = 0; k < num.length(); k++) {
355 TQ_INT32 st = num.at(k).digitValue() * 7;
356
357 p->drawPixmap(x, y, m_pixmapNums, st, 0, 7, 7);
358
359 if (orientationHoriz)
360 x += 7;
361 else
362 y += 8;
363 }
364}
365
366#include "kis_ruler.moc"
367