kdeui Library API Documentation

kruler.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1998 Jörg Habenicht (j.habenicht@europemail.com) 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 /************************************************************************* 00021 * $Id: kruler.cpp,v 1.19 2003/07/17 12:55:51 binner Exp $ 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 /* distance between 2 base marks in pixel */ 00045 #define INIT_OFFSET (-20) 00046 #define INIT_LENGTH_FIX true 00047 #define INIT_END_OFFSET 0 00048 00049 #define FIX_WIDTH 20 /* widget width in pixel */ 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; /* marks the offset at the end of the ruler 00084 * i.e. right side at horizontal and down side 00085 * at vertical rulers. 00086 * the ruler end mark is moved endOffset_length 00087 * ticks away from the widget end. 00088 * positive offset moves end mark inside the ruler. 00089 * if lengthFix is true, endOffset_length holds the 00090 * length of the ruler. 00091 */ 00092 int fontWidth; // ONLY valid for vertical rulers 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 {// debug("set range from %i to %i", min, max); 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 // premeasure the fontwidth and save it 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: /* fall through */ 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: /* fall through */ 00421 case Centimetres: /* fall through */ 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: /* never reached, see above switch */ 00452 /* empty command */; 00453 } 00454 // if the style changes one of the values, 00455 // update would have been called inside the methods 00456 // -> no update() call needed here ! 00457 } 00458 00459 void 00460 KRuler::setPixelPerMark(double rate) 00461 { // never compare floats against each other :) 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 {// debug("set offset %i", _offset); 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 // setValue(_value); 00551 range.setValue(_value); 00552 if (range.value() == oldvalue) { 00553 return; 00554 } 00555 // get the rectangular of the old and the new ruler pointer 00556 // and repaint only him 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 //setOffset(_offset); 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 // debug ("KRuler::drawContents, %s",(horizontal==dir)?"horizontal":"vertical"); 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 //ioffsetval = value-offset; 00622 // pixelpm = (int)ppm; 00623 // left = clip.left(), 00624 // right = clip.right(); 00625 double f, fend, 00626 offsetmin=(double)(minval-offset_), 00627 offsetmax=(double)(maxval-offset_), 00628 fontOffset = (((double)minval)>offsetmin)?(double)minval:offsetmin; 00629 00630 // draw labels 00631 QFont font = p->font(); 00632 font.setPointSize(LABEL_SIZE); 00633 p->setFont( font ); 00634 // draw littlemarklabel 00635 00636 // draw mediummarklabel 00637 00638 // draw bigmarklabel 00639 00640 // draw endlabel 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 { // rotate text +pi/2 and move down a bit 00647 //QFontMetrics fm(font); 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 // draw the tiny marks 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 // draw the little marks 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 // draw medium marks 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 // draw big marks 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 // draw end marks 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 // draw pointer 00722 if (d->showpointer) { 00723 QPointArray pa(4); 00724 if (dir == Horizontal) { 00725 pa.setPoints(3, value-5, 10, value+5, 10, value/*+0*/,15); 00726 } 00727 else { 00728 pa.setPoints(3, 10, value-5, 10, value+5, 15, value/*+0*/); 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 { /*BASE::virtual_hook( id, data );*/ } 00744 00745 #include "kruler.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Aug 30 22:53:59 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003