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