00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "kruler.h"
00025
00026 #include <qpainter.h>
00027 #include <qfont.h>
00028
00029 #define INIT_VALUE 0
00030 #define INIT_MIN_VALUE 0
00031 #define INIT_MAX_VALUE 100
00032 #define INIT_TINY_MARK_DISTANCE 1
00033 #define INIT_LITTLE_MARK_DISTANCE 5
00034 #define INIT_MIDDLE_MARK_DISTANCE (INIT_LITTLE_MARK_DISTANCE * 2)
00035 #define INIT_BIG_MARK_DISTANCE (INIT_LITTLE_MARK_DISTANCE * 10)
00036 #define INIT_SHOW_TINY_MARK false
00037 #define INIT_SHOW_LITTLE_MARK true
00038 #define INIT_SHOW_MEDIUM_MARK true
00039 #define INIT_SHOW_BIG_MARK true
00040 #define INIT_SHOW_END_MARK true
00041 #define INIT_SHOW_POINTER true
00042 #define INIT_SHOW_END_LABEL true
00043
00044 #define INIT_PIXEL_PER_MARK (double)10.0
00045 #define INIT_OFFSET (-20)
00046 #define INIT_LENGTH_FIX true
00047 #define INIT_END_OFFSET 0
00048
00049 #define FIX_WIDTH 20
00050 #define LINE_END (FIX_WIDTH - 3)
00051 #define END_MARK_LENGTH (FIX_WIDTH - 6)
00052 #define END_MARK_X2 LINE_END
00053 #define END_MARK_X1 (END_MARK_X2 - END_MARK_LENGTH)
00054 #define BIG_MARK_LENGTH (END_MARK_LENGTH*3/4)
00055 #define BIG_MARK_X2 LINE_END
00056 #define BIG_MARK_X1 (BIG_MARK_X2 - BIG_MARK_LENGTH)
00057 #define MIDDLE_MARK_LENGTH (END_MARK_LENGTH/2)
00058 #define MIDDLE_MARK_X2 LINE_END
00059 #define MIDDLE_MARK_X1 (MIDDLE_MARK_X2 - MIDDLE_MARK_LENGTH)
00060 #define LITTLE_MARK_LENGTH (MIDDLE_MARK_LENGTH/2)
00061 #define LITTLE_MARK_X2 LINE_END
00062 #define LITTLE_MARK_X1 (LITTLE_MARK_X2 - LITTLE_MARK_LENGTH)
00063 #define BASE_MARK_LENGTH (LITTLE_MARK_LENGTH/2)
00064 #define BASE_MARK_X2 LINE_END
00065 #define BASE_MARK_X1 (BASE_MARK_X2 - BASE_MARK_LENGTH)
00066
00067 #define LABEL_SIZE 8
00068 #define END_LABEL_X 4
00069 #define END_LABEL_Y (END_LABEL_X + LABEL_SIZE - 2)
00070
00071 #undef PROFILING
00072
00073 #ifdef PROFILING
00074 # include <qdatetime.h>
00075 #endif
00076
00077 class KRuler::KRulerPrivate
00078 {
00079 public:
00080 bool showpointer;
00081 bool showEndL;
00082 bool lengthFix;
00083 int endOffset_length;
00084
00085
00086
00087
00088
00089
00090
00091
00092 int fontWidth;
00093 };
00094
00095
00096
00097 KRuler::KRuler(QWidget *parent, const char *name)
00098 : QFrame(parent, name),
00099 range(INIT_MIN_VALUE, INIT_MAX_VALUE, 1, 10, INIT_VALUE),
00100 dir(Horizontal)
00101 {
00102 init();
00103 setFixedHeight(FIX_WIDTH);
00104 }
00105
00106
00107 KRuler::KRuler(Orientation orient,
00108 QWidget *parent, const char *name, WFlags f)
00109 : QFrame(parent, name, f),
00110 range(INIT_MIN_VALUE, INIT_MAX_VALUE, 1, 10, INIT_VALUE),
00111 dir(orient)
00112 {
00113 init();
00114 if (orient == Horizontal)
00115 setFixedHeight(FIX_WIDTH);
00116 else
00117 setFixedWidth(FIX_WIDTH);
00118 }
00119
00120
00121 KRuler::KRuler(Orientation orient, int widgetWidth,
00122 QWidget *parent, const char *name, WFlags f)
00123 : QFrame(parent, name, f),
00124 range(INIT_MIN_VALUE, INIT_MAX_VALUE, 1, 10, INIT_VALUE),
00125 dir(orient)
00126 {
00127 init();
00128
00129 if (orient == Horizontal)
00130 setFixedHeight(widgetWidth);
00131 else
00132 setFixedWidth(widgetWidth);
00133 }
00134
00135
00136 void KRuler::init()
00137 {
00138 setFrameStyle(WinPanel | Raised);
00139
00140 tmDist = INIT_TINY_MARK_DISTANCE;
00141 lmDist = INIT_LITTLE_MARK_DISTANCE;
00142 mmDist = INIT_MIDDLE_MARK_DISTANCE;
00143 bmDist = INIT_BIG_MARK_DISTANCE;
00144 offset_= INIT_OFFSET;
00145 showtm = INIT_SHOW_TINY_MARK;
00146 showlm = INIT_SHOW_LITTLE_MARK;
00147 showmm = INIT_SHOW_MEDIUM_MARK;
00148 showbm = INIT_SHOW_BIG_MARK;
00149 showem = INIT_SHOW_END_MARK;
00150 ppm = INIT_PIXEL_PER_MARK;
00151
00152 d = new KRuler::KRulerPrivate;
00153 d->showpointer = INIT_SHOW_POINTER;
00154 d->showEndL = INIT_SHOW_END_LABEL;
00155 d->lengthFix = INIT_LENGTH_FIX;
00156 d->endOffset_length = INIT_END_OFFSET;
00157 }
00158
00159
00160 KRuler::~KRuler()
00161 {
00162 delete d;
00163 }
00164
00165 void
00166 KRuler::setMinValue(int value)
00167 {
00168 if (range.minValue() != value) {
00169 range.setRange( value, range.maxValue() );
00170 update(contentsRect());
00171 }
00172 }
00173
00174 void
00175 KRuler::setMaxValue(int value)
00176 {
00177 if (range.maxValue() != value) {
00178 range.setRange( range.minValue(), value );
00179 update(contentsRect());
00180 }
00181 }
00182
00183 void
00184 KRuler::setRange(int min, int max)
00185 {
00186 if ((range.minValue() != min) || (range.maxValue() != max)) {
00187 range.setRange( min, max );
00188 update(contentsRect());
00189 }
00190 }
00191
00192 void
00193 KRuler::setValue(int value)
00194 {
00195 range.setValue(value);
00196 update(contentsRect());
00197 }
00198
00199 void
00200 KRuler::setTinyMarkDistance(int dist)
00201 {
00202 if (dist != tmDist) {
00203 tmDist = dist;
00204 update(contentsRect());
00205 }
00206 }
00207
00208 void
00209 KRuler::setLittleMarkDistance(int dist)
00210 {
00211 if (dist != lmDist) {
00212 lmDist = dist;
00213 update(contentsRect());
00214 }
00215 }
00216
00217 void
00218 KRuler::setMediumMarkDistance(int dist)
00219 {
00220 if (dist != mmDist) {
00221 mmDist = dist;
00222 update(contentsRect());
00223 }
00224 }
00225
00226 void
00227 KRuler::setBigMarkDistance(int dist)
00228 {
00229 if (dist != bmDist) {
00230 bmDist = dist;
00231 update(contentsRect());
00232 }
00233 }
00234
00235 void
00236 KRuler::setShowTinyMarks(bool show)
00237 {
00238 if (show != showtm) {
00239 showtm = show;
00240 update(contentsRect());
00241 }
00242 }
00243
00244 bool
00245 KRuler::showTinyMarks() const
00246 {
00247 return showtm;
00248 }
00249
00250 void
00251 KRuler::setShowLittleMarks(bool show)
00252 {
00253 if (show != showlm) {
00254 showlm = show;
00255 update(contentsRect());
00256 }
00257 }
00258
00259 bool
00260 KRuler::showLittleMarks() const
00261 {
00262 return showlm;
00263 }
00264
00265 void
00266 KRuler::setShowMediumMarks(bool show)
00267 {
00268 if (show != showmm) {
00269 showmm = show;
00270 update(contentsRect());
00271 }
00272 }
00273
00274 bool
00275 KRuler::showMediumMarks() const
00276 {
00277 return showmm;
00278 }
00279
00280 void
00281 KRuler::setShowBigMarks(bool show)
00282 {
00283 if (show != showbm) {
00284 showbm = show;
00285 update(contentsRect());
00286 }
00287 }
00288
00289
00290 bool
00291 KRuler::showBigMarks() const
00292 {
00293 return showbm;
00294 }
00295
00296 void
00297 KRuler::setShowEndMarks(bool show)
00298 {
00299 if (show != showem) {
00300 showem = show;
00301 update(contentsRect());
00302 }
00303 }
00304
00305 bool
00306 KRuler::showEndMarks() const
00307 {
00308 return showem;
00309 }
00310
00311 void
00312 KRuler::setShowPointer(bool show)
00313 {
00314 if (show != d->showpointer) {
00315 d->showpointer = show;
00316 update(contentsRect());
00317 }
00318 }
00319
00320
00321 bool
00322 KRuler::showPointer() const
00323 {
00324 return d->showpointer;
00325 }
00326
00327 void
00328 KRuler::setValuePerLittleMark(int)
00329 {
00330 update(contentsRect());
00331 }
00332
00333 void
00334 KRuler::setValuePerMediumMark(int)
00335 {
00336 update(contentsRect());
00337 }
00338
00339 void
00340 KRuler::setValuePerBigMark(int)
00341 {
00342 update(contentsRect());
00343 }
00344
00345 void
00346 KRuler::setShowEndLabel(bool show)
00347 {
00348 if (d->showEndL != show) {
00349 d->showEndL = show;
00350 update(contentsRect());
00351 }
00352 }
00353
00354
00355 bool
00356 KRuler::showEndLabel() const
00357 {
00358 return d->showEndL;
00359 }
00360
00361
00362 void
00363 KRuler::setEndLabel(const QString& label)
00364 {
00365 endlabel = label;
00366
00367
00368 if (dir == Vertical) {
00369 QFont font = this->font();
00370 font.setPointSize(LABEL_SIZE);
00371 QFontMetrics fm(font);
00372 d->fontWidth = fm.width(endlabel);
00373 }
00374 update(contentsRect());
00375 }
00376
00377 QString KRuler::endLabel() const
00378 {
00379 return endlabel;
00380 }
00381
00382 void
00383 KRuler::setRulerMetricStyle(KRuler::MetricStyle style)
00384 {
00385 switch (style) {
00386 default:
00387 case Custom:
00388 return;
00389 case Pixel:
00390 setLittleMarkDistance(1);
00391 setMediumMarkDistance(5);
00392 setBigMarkDistance(10);
00393
00394 setShowTinyMarks(false);
00395 setShowLittleMarks(true);
00396 setShowMediumMarks(true);
00397 setShowBigMarks(true);
00398 setShowEndMarks(true);
00399
00400 setValuePerMediumMark(50);
00401 setPixelPerMark(10.0);
00402
00403 break;
00404 case Inch:
00405 setTinyMarkDistance(1);
00406 setLittleMarkDistance(2);
00407 setMediumMarkDistance(4);
00408 setBigMarkDistance(8);
00409
00410 setShowTinyMarks(true);
00411 setShowLittleMarks(true);
00412 setShowMediumMarks(true);
00413 setShowBigMarks(true);
00414 setShowEndMarks(true);
00415
00416 setValuePerBigMark(1);
00417 setPixelPerMark(9.0);
00418
00419 break;
00420 case Millimetres:
00421 case Centimetres:
00422 case Metres:
00423 setLittleMarkDistance(1);
00424 setMediumMarkDistance(5);
00425 setBigMarkDistance(10);
00426
00427 setShowTinyMarks(false);
00428 setShowLittleMarks(true);
00429 setShowMediumMarks(true);
00430 setShowBigMarks(true);
00431 setShowEndMarks(true);
00432
00433 setValuePerBigMark(10);
00434 setPixelPerMark(3.0);
00435 }
00436 switch (style) {
00437 case Pixel:
00438 setEndLabel(QString::fromLatin1("pixel"));
00439 break;
00440 case Inch:
00441 setEndLabel(QString::fromLatin1("inch"));
00442 break;
00443 case Millimetres:
00444 setEndLabel(QString::fromLatin1("mm"));
00445 break;
00446 case Centimetres:
00447 setEndLabel(QString::fromLatin1("cm"));
00448 break;
00449 case Metres:
00450 setEndLabel(QString::fromLatin1("m"));
00451 default:
00452 ;
00453 }
00454
00455
00456
00457 }
00458
00459 void
00460 KRuler::setPixelPerMark(double rate)
00461 {
00462 ppm = rate;
00463 update(contentsRect());
00464 }
00465
00466
00467 void
00468 KRuler::setLength(int length)
00469 {
00470 int tmp;
00471 if (d->lengthFix) {
00472 tmp = length;
00473 }
00474 else {
00475 tmp = this->width() - length;
00476 }
00477 if (tmp != d->endOffset_length) {
00478 d->endOffset_length = tmp;
00479 update(contentsRect());
00480 }
00481 }
00482
00483 int
00484 KRuler::length() const
00485 {
00486 if (d->lengthFix) {
00487 return d->endOffset_length;
00488 }
00489 return (this->width() - d->endOffset_length);
00490 }
00491
00492
00493 void
00494 KRuler::setLengthFixed(bool fix)
00495 {
00496 d->lengthFix = fix;
00497 }
00498
00499 bool
00500 KRuler::lengthFixed() const
00501 {
00502 return d->lengthFix;
00503 }
00504
00505 void
00506 KRuler::setOffset(int _offset)
00507 {
00508 if (offset_ != _offset) {
00509 offset_ = _offset;
00510 update(contentsRect());
00511 }
00512 }
00513
00514 int
00515 KRuler::endOffset() const
00516 {
00517 if (d->lengthFix) {
00518 return (this->width() - d->endOffset_length);
00519 }
00520 return d->endOffset_length;
00521 }
00522
00523
00524 void
00525 KRuler::slideUp(int count)
00526 {
00527 if (count) {
00528 offset_ += count;
00529 update(contentsRect());
00530 }
00531 }
00532
00533 void
00534 KRuler::slideDown(int count)
00535 {
00536 if (count) {
00537 offset_ -= count;
00538 update(contentsRect());
00539 }
00540 }
00541
00542
00543 void
00544 KRuler::slotNewValue(int _value)
00545 {
00546 int oldvalue = range.value();
00547 if (oldvalue == _value) {
00548 return;
00549 }
00550
00551 range.setValue(_value);
00552 if (range.value() == oldvalue) {
00553 return;
00554 }
00555
00556
00557 if (dir == Horizontal) {
00558 QRect oldrec(-5+oldvalue,10, 11,6);
00559 QRect newrec(-5+_value,10, 11,6);
00560 repaint( oldrec.unite(newrec) );
00561 }
00562 else {
00563 QRect oldrec(10,-5+oldvalue, 6,11);
00564 QRect newrec(10,-5+_value, 6,11);
00565 repaint( oldrec.unite(newrec) );
00566 }
00567 }
00568
00569 void
00570 KRuler::slotNewOffset(int _offset)
00571 {
00572 if (offset_ != _offset) {
00573
00574 offset_ = _offset;
00575 repaint(contentsRect());
00576 }
00577 }
00578
00579
00580 void
00581 KRuler::slotEndOffset(int offset)
00582 {
00583 int tmp;
00584 if (d->lengthFix) {
00585 tmp = this->width() - offset;
00586 }
00587 else {
00588 tmp = offset;
00589 }
00590 if (d->endOffset_length != tmp) {
00591 d->endOffset_length = tmp;
00592 repaint(contentsRect());
00593 }
00594 }
00595
00596 void
00597 KRuler::drawContents(QPainter *p)
00598 {
00599
00600
00601 #ifdef PROFILING
00602 QTime time;
00603 time.start();
00604 for (int profile=0; profile<10; profile++) {
00605 #endif
00606
00607 int value = range.value(),
00608 minval = range.minValue(),
00609 maxval;
00610 if (dir == Horizontal) {
00611 maxval = range.maxValue()
00612 + offset_
00613 - (d->lengthFix?(height()-d->endOffset_length):d->endOffset_length);
00614 }
00615 else
00616 {
00617 maxval = range.maxValue()
00618 + offset_
00619 - (d->lengthFix?(width()-d->endOffset_length):d->endOffset_length);
00620 }
00621
00622
00623
00624
00625 double f, fend,
00626 offsetmin=(double)(minval-offset_),
00627 offsetmax=(double)(maxval-offset_),
00628 fontOffset = (((double)minval)>offsetmin)?(double)minval:offsetmin;
00629
00630
00631 QFont font = p->font();
00632 font.setPointSize(LABEL_SIZE);
00633 p->setFont( font );
00634
00635
00636
00637
00638
00639
00640
00641 if (d->showEndL) {
00642 if (dir == Horizontal) {
00643 p->translate( fontOffset, 0 );
00644 p->drawText( END_LABEL_X, END_LABEL_Y, endlabel );
00645 }
00646 else {
00647
00648 #ifdef KRULER_ROTATE_TEST
00649 p->rotate( -90.0 + rotate );
00650 p->translate( -8.0 - fontOffset - d->fontWidth + xtrans,
00651 ytrans );
00652 #else
00653 p->rotate( -90.0 );
00654 p->translate( -8.0 - fontOffset - d->fontWidth, 0.0 );
00655 #endif
00656 p->drawText( END_LABEL_X, END_LABEL_Y, endlabel );
00657 }
00658 p->resetXForm();
00659 }
00660
00661
00662 if (showtm) {
00663 fend = ppm*tmDist;
00664 for ( f=offsetmin; f<offsetmax; f+=fend ) {
00665 if (dir == Horizontal) {
00666 p->drawLine((int)f, BASE_MARK_X1, (int)f, BASE_MARK_X2);
00667 }
00668 else {
00669 p->drawLine(BASE_MARK_X1, (int)f, BASE_MARK_X2, (int)f);
00670 }
00671 }
00672 }
00673 if (showlm) {
00674
00675 fend = ppm*lmDist;
00676 for ( f=offsetmin; f<offsetmax; f+=fend ) {
00677 if (dir == Horizontal) {
00678 p->drawLine((int)f, LITTLE_MARK_X1, (int)f, LITTLE_MARK_X2);
00679 }
00680 else {
00681 p->drawLine(LITTLE_MARK_X1, (int)f, LITTLE_MARK_X2, (int)f);
00682 }
00683 }
00684 }
00685 if (showmm) {
00686
00687 fend = ppm*mmDist;
00688 for ( f=offsetmin; f<offsetmax; f+=fend ) {
00689 if (dir == Horizontal) {
00690 p->drawLine((int)f, MIDDLE_MARK_X1, (int)f, MIDDLE_MARK_X2);
00691 }
00692 else {
00693 p->drawLine(MIDDLE_MARK_X1, (int)f, MIDDLE_MARK_X2, (int)f);
00694 }
00695 }
00696 }
00697 if (showbm) {
00698
00699 fend = ppm*bmDist;
00700 for ( f=offsetmin; f<offsetmax; f+=fend ) {
00701 if (dir == Horizontal) {
00702 p->drawLine((int)f, BIG_MARK_X1, (int)f, BIG_MARK_X2);
00703 }
00704 else {
00705 p->drawLine(BIG_MARK_X1, (int)f, BIG_MARK_X2, (int)f);
00706 }
00707 }
00708 }
00709 if (showem) {
00710
00711 if (dir == Horizontal) {
00712 p->drawLine(minval-offset_, END_MARK_X1, minval-offset_, END_MARK_X2);
00713 p->drawLine(maxval-offset_, END_MARK_X1, maxval-offset_, END_MARK_X2);
00714 }
00715 else {
00716 p->drawLine(END_MARK_X1, minval-offset_, END_MARK_X2, minval-offset_);
00717 p->drawLine(END_MARK_X1, maxval-offset_, END_MARK_X2, maxval-offset_);
00718 }
00719 }
00720
00721
00722 if (d->showpointer) {
00723 QPointArray pa(4);
00724 if (dir == Horizontal) {
00725 pa.setPoints(3, value-5, 10, value+5, 10, value,15);
00726 }
00727 else {
00728 pa.setPoints(3, 10, value-5, 10, value+5, 15, value);
00729 }
00730 p->setBrush( p->backgroundColor() );
00731 p->drawPolygon( pa );
00732 }
00733
00734 #ifdef PROFILING
00735 }
00736 int elapsed = time.elapsed();
00737 debug("paint time %i",elapsed);
00738 #endif
00739
00740 }
00741
00742 void KRuler::virtual_hook( int, void* )
00743 { }
00744
00745 #include "kruler.moc"