krita

kis_ruler.cc

00001 /*
00002  * Kivio - Visual Modelling and Flowcharting
00003  * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
00004  * Copyright (C) 2002 Patrick Julien <freak@codepimps.org>
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  */
00020 #include <qpainter.h>
00021 
00022 #include "kdebug.h"
00023 
00024 #include "kis_ruler.h"
00025 
00026 #define MARKER_WIDTH 1
00027 #define MARKER_HEIGHT RULER_THICKNESS
00028 
00029 const char *KisRuler::m_nums[] = {
00030     "70 7 2 1",
00031     "  c Black",
00032     "X c None",
00033     "XX   XXXXXX XXXX   XXXX   XXXXXX XXX     XXXX  XXX     XXX   XXXX   XX",
00034     "X XXX XXXX  XXX XXX XX XXX XXXX  XXX XXXXXXX XXXXXXXXX XX XXX XX XXX X",
00035     "X XXX XXXXX XXXXXXX XXXXXX XXX X XXX XXXXXX XXXXXXXXX XXX XXX XX XXX X",
00036     "X XXX XXXXX XXXXX  XXXXX  XXX XX XXX    XXX    XXXXXX XXXX   XXXX    X",
00037     "X XXX XXXXX XXXX XXXXXXXXX XX     XXXXXX XX XXX XXXX XXXX XXX XXXXXX X",
00038     "X XXX XXXXX XXX XXXXXX XXX XXXXX XXXXXXX XX XXX XXXX XXXX XXX XXXXX XX",
00039     "XX   XXXXXX XXX     XXX   XXXXXX XXX    XXXX   XXXXX XXXXX   XXXX  XXX"
00040 };
00041 
00042 KisRuler::KisRuler(Qt::Orientation o, QWidget *parent, const char *name) : super(parent, name, WRepaintNoErase | WResizeNoErase), m_pixmapNums(m_nums)
00043 {
00044     setBackgroundMode(NoBackground);
00045     setFrameStyle(Box | Sunken);
00046     setLineWidth(1);
00047     setMidLineWidth(0);
00048     m_orientation = o;
00049     m_unit = KoUnit::U_PT;
00050     m_zoom = 1.0;
00051     m_firstVisible = 0;
00052     m_pixmapBuffer = 0;
00053     m_currentPosition = -1;
00054 
00055     if (m_orientation == Qt::Horizontal) {
00056         setFixedHeight(RULER_THICKNESS);
00057         initMarker(MARKER_WIDTH, MARKER_HEIGHT);
00058     } else {
00059         setFixedWidth(RULER_THICKNESS);
00060         initMarker(MARKER_HEIGHT, MARKER_WIDTH);
00061     }
00062 }
00063 
00064 KisRuler::~KisRuler()
00065 {
00066     delete m_pixmapBuffer;
00067 }
00068 
00069 void KisRuler::initMarker(Q_INT32 w, Q_INT32 h)
00070 {
00071     QPainter p;
00072 
00073     m_pixmapMarker.resize(w, h);
00074     p.begin(&m_pixmapMarker);
00075     p.setPen(blue);
00076     p.eraseRect(0, 0, w, h);
00077     p.drawLine(0, 0, w - 1, h - 1);
00078     p.end();
00079 }
00080 
00081 void KisRuler::recalculateSize()
00082 {
00083     Q_INT32 w;
00084     Q_INT32 h;
00085 
00086     if (m_pixmapBuffer) {
00087         delete m_pixmapBuffer;
00088         m_pixmapBuffer = 0;
00089     }
00090 
00091     if (m_orientation == Qt::Horizontal) {
00092         w = width();
00093         h = RULER_THICKNESS;
00094     } else {
00095         w = RULER_THICKNESS;
00096         h = height();
00097     }
00098 
00099     m_pixmapBuffer = new QPixmap(w, h);
00100     Q_CHECK_PTR(m_pixmapBuffer);
00101 
00102     drawRuler();
00103     updatePointer(m_currentPosition, m_currentPosition);
00104 }
00105 
00106 KoUnit::Unit KisRuler::unit() const
00107 {
00108     return  m_unit;
00109 }
00110 
00111 void KisRuler::setUnit(KoUnit::Unit u)
00112 {
00113     m_unit = u;
00114     drawRuler();
00115     updatePointer(m_currentPosition, m_currentPosition);
00116     update();
00117 }
00118 
00119 void KisRuler::setZoom(double zoom)
00120 {
00121     m_zoom = zoom;
00122     recalculateSize();
00123     drawRuler();
00124     updatePointer(m_currentPosition, m_currentPosition);
00125     update();
00126 }
00127 
00128 void KisRuler::updatePointer(Q_INT32 x, Q_INT32 y)
00129 {
00130     if (m_pixmapBuffer) {
00131         if (m_orientation == Qt::Horizontal) {
00132             if (m_currentPosition != -1)
00133                 repaint(m_currentPosition, 1, MARKER_WIDTH, MARKER_HEIGHT);
00134 
00135             if (x != -1) {
00136                 bitBlt(this, x, 1, &m_pixmapMarker, 0, 0, MARKER_WIDTH, MARKER_HEIGHT);
00137                 m_currentPosition = x;
00138             }
00139         } else {
00140             if (m_currentPosition != -1)
00141                 repaint(1, m_currentPosition, MARKER_HEIGHT, MARKER_WIDTH);
00142 
00143             if (y != -1) {
00144                 bitBlt(this, 1, y, &m_pixmapMarker, 0, 0, MARKER_HEIGHT, MARKER_WIDTH);
00145                 m_currentPosition = y;
00146             }
00147         }
00148     }
00149 }
00150 
00151 void KisRuler::updateVisibleArea(Q_INT32 xpos, Q_INT32 ypos)
00152 {
00153     if (m_orientation == Qt::Horizontal)
00154         m_firstVisible = xpos;
00155     else
00156         m_firstVisible = ypos;
00157 
00158     drawRuler();
00159     update();
00160     updatePointer(m_currentPosition, m_currentPosition);
00161 }
00162 
00163 void KisRuler::paintEvent(QPaintEvent *e)
00164 {
00165     if (m_pixmapBuffer) {
00166         const QRect& rect = e->rect();
00167 
00168         bitBlt(this, rect.topLeft(), m_pixmapBuffer, rect);
00169         super::paintEvent(e);
00170     }
00171 }
00172 
00173 void KisRuler::drawRuler()
00174 {
00175     QPainter p;
00176     QString buf;
00177     Q_INT32 st1 = 0;
00178     Q_INT32 st2 = 0;
00179     Q_INT32 st3 = 0;
00180     Q_INT32 st4 = 0;
00181 
00182     if (!m_pixmapBuffer)
00183         return;
00184 
00185     p.begin(m_pixmapBuffer);
00186     p.setPen(colorGroup().text());
00187     p.setBackgroundColor(colorGroup().base());
00188     p.eraseRect(0, 0, m_pixmapBuffer->width(), m_pixmapBuffer->height());
00189 
00190     switch (m_unit) {
00191         case KoUnit::U_PT:
00192         case KoUnit::U_MM:
00193         case KoUnit::U_DD:
00194         case KoUnit::U_CC:
00195             st1 = 1;
00196             st2 = 5;
00197             st3 = 10;
00198             st4 = 25;
00199             break;
00200         case KoUnit::U_CM:
00201         case KoUnit::U_PI:
00202         case KoUnit::U_INCH:
00203         default:
00204             st1 = 1;
00205             st2 = 2;
00206             st3 = 5;
00207             st4 = 10;
00208     }
00209 
00210     bool s1 = KoUnit::fromUserValue(st1, m_unit) * m_zoom > 3.0;
00211     bool s2 = KoUnit::fromUserValue(st2, m_unit) * m_zoom > 3.0;
00212     bool s3 = KoUnit::fromUserValue(st3, m_unit) * m_zoom > 3.0;
00213     bool s4 = KoUnit::fromUserValue(st4, m_unit) * m_zoom > 3.0;
00214 
00215     float cx = KoUnit::fromUserValue(100, m_unit) / m_zoom;
00216     Q_INT32 step = qRound(cx);
00217 
00218     if (step < 5) {
00219         step = 1;
00220     } else if (step < 10) {
00221         step = 5;
00222     } else if (step < 25) {
00223         step = 10;
00224     } else if (step < 50) {
00225         step = 25;
00226     } else if (step < 100) {
00227         step = 50;
00228     } else if (step < 250) {
00229         step = 100;
00230     } else if (step < 500) {
00231         step = 250;
00232     } else if (step < 1000) {
00233         step = 500;
00234     } else if (step < 2500) {
00235         step = 1000;
00236     } else if (step < 5000) {
00237         step = 2500;
00238     } else if (step < 10000) {
00239         step = 5000;
00240     } else  if (step < 25000) {
00241         step = 10000;
00242     } else if (step < 50000) {
00243         step = 25000;
00244     } else if (step < 100000) {
00245         step = 50000;
00246     } else {
00247         step = 100000;
00248     }
00249 
00250     Q_INT32 start = (Q_INT32)(KoUnit::fromUserValue(m_firstVisible, m_unit) / m_zoom);
00251     Q_INT32 pos = 0;
00252 
00253     if (m_orientation == Qt::Horizontal) {
00254         do {
00255             pos = (Q_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible);
00256 
00257             if (!s3 && s4 && start % st4 == 0)
00258                 p.drawLine(pos, RULER_THICKNESS - 9, pos, RULER_THICKNESS);
00259 
00260             if (s3 && start % st3 == 0)
00261                 p.drawLine(pos, RULER_THICKNESS - 9, pos, RULER_THICKNESS);
00262 
00263             if (s2 && start % st2 == 0)
00264                 p.drawLine(pos, RULER_THICKNESS - 7, pos, RULER_THICKNESS);
00265 
00266             if (s1 && start % st1 == 0)
00267                 p.drawLine(pos, RULER_THICKNESS - 5, pos, RULER_THICKNESS);
00268 
00269             if (start % step == 0) {
00270                 buf.setNum(QABS(start));
00271                 drawNums(&p, pos, 4, buf, true);
00272             }
00273 
00274             start++;
00275         } while (pos < m_pixmapBuffer->width());
00276     } else {
00277         do {
00278             pos = (Q_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible);
00279 
00280             if (!s3 && s4 && start % st4 == 0)
00281                 p.drawLine(RULER_THICKNESS - 9, pos, RULER_THICKNESS, pos);
00282 
00283             if (s3 && start % st3 == 0)
00284                 p.drawLine(RULER_THICKNESS - 9, pos, RULER_THICKNESS, pos);
00285 
00286             if (s2 && start % st2 == 0)
00287                 p.drawLine(RULER_THICKNESS - 7, pos, RULER_THICKNESS, pos);
00288 
00289             if (s1 && start % st1 == 0)
00290                 p.drawLine(RULER_THICKNESS - 5, pos, RULER_THICKNESS, pos);
00291 
00292             if (start % step == 0) {
00293                 buf.setNum(QABS(start));
00294                 drawNums(&p, 4, pos, buf, false);
00295             }
00296 
00297             start++;
00298         } while (pos < m_pixmapBuffer->height());
00299     }
00300 
00301     p.end();
00302 }
00303 
00304 void KisRuler::resizeEvent(QResizeEvent *)
00305 {
00306     recalculateSize();
00307 }
00308 
00309 void KisRuler::styleChange(QStyle& oldStyle)
00310 {
00311     Q_UNUSED(oldStyle);
00312     updateGeometry();
00313     drawRuler();
00314 }
00315 
00316 void KisRuler::paletteChange(const QPalette& oldPalette)
00317 {
00318     Q_UNUSED(oldPalette);
00319     drawRuler();
00320 }
00321 
00322 void KisRuler::show()
00323 {
00324     if (m_orientation == Qt::Horizontal) {
00325         setFixedHeight(RULER_THICKNESS);
00326         initMarker(MARKER_WIDTH, MARKER_HEIGHT);
00327     } else {
00328         setFixedWidth(RULER_THICKNESS);
00329         initMarker(MARKER_HEIGHT, MARKER_WIDTH);
00330     }
00331 
00332     super::show();
00333 }
00334 
00335 void KisRuler::hide()
00336 {
00337     /*
00338     if (m_orientation == Qt::Horizontal)
00339         setFixedHeight(1);
00340     else
00341         setFixedWidth(1);
00342         */
00343     super::hide();
00344 }
00345 
00346 void KisRuler::drawNums(QPainter *p, Q_INT32 x, Q_INT32 y, QString& num, bool orientationHoriz)
00347 {
00348     if (orientationHoriz)
00349         x -= 7;
00350     else
00351         y -= 8;
00352 
00353     for (Q_UINT32 k = 0; k < num.length(); k++) {
00354         Q_INT32 st = num.at(k).digitValue() * 7;
00355 
00356         p->drawPixmap(x, y, m_pixmapNums, st, 0, 7, 7);
00357 
00358         if (orientationHoriz)
00359             x += 7;
00360         else
00361             y += 8;
00362     }
00363 }
00364 
00365 #include "kis_ruler.moc"
00366 
KDE Home | KDE Accessibility Home | Description of Access Keys