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