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