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