karbon

vruler.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 "vruler.h"
00025 
00026 #define MARKER_WIDTH 1
00027 #define MARKER_HEIGHT 20
00028 #define RULER_SIZE 20
00029 
00030 const char *VRuler::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 VRuler::VRuler(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_SIZE);
00058         initMarker(MARKER_WIDTH, MARKER_HEIGHT);
00059     } else {
00060         setFixedWidth(RULER_SIZE);
00061         initMarker(MARKER_HEIGHT, MARKER_WIDTH);
00062     }
00063 }
00064 
00065 VRuler::~VRuler()
00066 {
00067     delete m_pixmapBuffer;
00068 }
00069 
00070 void VRuler::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 VRuler::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_SIZE;
00095     } else {
00096         w = RULER_SIZE;
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 VRuler::unit() const
00108 {
00109     return  m_unit;
00110 }
00111 
00112 void VRuler::setUnit(KoUnit::Unit u)
00113 {
00114     m_unit = u;
00115     drawRuler();
00116     updatePointer(m_currentPosition, m_currentPosition);
00117     repaint();
00118 }
00119 
00120 void VRuler::setZoom(double zoom)
00121 {
00122     m_zoom = zoom;
00123     recalculateSize();
00124     drawRuler();
00125     updatePointer(m_currentPosition, m_currentPosition);
00126     repaint();
00127 }
00128 
00129 void VRuler::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 VRuler::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     //kdDebug() << "--###-- VRuler::updateVisibleArea(" << xpos << ", " << ypos << ")" << endl;
00160     drawRuler();
00161     repaint();
00162     updatePointer(m_currentPosition, m_currentPosition);
00163     //kdDebug() << "--###-- VRuler::updatePointer(" << m_currentPosition << ", " << m_currentPosition << ")" << endl;
00164 }
00165 
00166 void VRuler::paintEvent(QPaintEvent *e)
00167 {
00168     if (m_pixmapBuffer) {
00169         const QRect& rect = e -> rect();
00170 
00171         bitBlt(this, rect.topLeft(), m_pixmapBuffer, rect);
00172         super::paintEvent(e);
00173     }
00174 }
00175 
00176 void VRuler::drawRuler()
00177 {
00178     QPainter p;
00179     QString buf;
00180     Q_INT32 st1 = 0;
00181     Q_INT32 st2 = 0;
00182     Q_INT32 st3 = 0;
00183     Q_INT32 st4 = 0;
00184     Q_INT32 stt = 0;
00185 
00186     if (!m_pixmapBuffer)
00187         return;
00188 
00189     p.begin(m_pixmapBuffer);
00190     p.setPen(QColor(0x70, 0x70, 0x70));
00191     p.setBackgroundColor(colorGroup().background());
00192     p.eraseRect(0, 0, m_pixmapBuffer -> width(), m_pixmapBuffer -> height());
00193 
00194     switch (m_unit) {
00195         case KoUnit::U_PT:
00196         case KoUnit::U_MM:
00197         case KoUnit::U_DD:
00198         case KoUnit::U_CC:
00199             st1 = 1;
00200             st2 = 5;
00201             st3 = 10;
00202             st4 = 25;
00203             stt = 100;
00204             break;
00205         case KoUnit::U_CM:
00206         case KoUnit::U_PI:
00207         case KoUnit::U_INCH:
00208             st1 = 1;
00209             st2 = 2;
00210             st3 = 5;
00211             st4 = 10;
00212             stt = 1;
00213             break;
00214         default:
00215             break;
00216     }
00217 
00218     Q_INT32 pos = 0;
00219     bool s1 = KoUnit::fromUserValue(st1, m_unit) * m_zoom > 3.0;
00220     bool s2 = KoUnit::fromUserValue(st2, m_unit) * m_zoom > 3.0;
00221     bool s3 = KoUnit::fromUserValue(st3, m_unit) * m_zoom > 3.0;
00222     bool s4 = KoUnit::fromUserValue(st4, m_unit) * m_zoom > 3.0;
00223 
00224     if (m_orientation == Qt::Horizontal) {
00225         // XXX: This was 7 * 4 -- why? what was the idea about having 30 point intervals?
00226         float cx = KoUnit::fromUserValue(100, m_unit) / m_zoom;
00227         Q_INT32 step = qRound(cx);//((Q_INT32)(cx / (float)stt) + 1) * stt;
00228         Q_INT32 start = (Q_INT32)(KoUnit::toUserValue(m_firstVisible, m_unit) / m_zoom);
00229 
00230         do {
00231             pos = (Q_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible);
00232 
00233             if (!s3 && s4 && start % st4 == 0)
00234                 p.drawLine(pos, RULER_SIZE - 9, pos, RULER_SIZE);
00235 
00236             if (s3 && start % st3 == 0)
00237                 p.drawLine(pos, RULER_SIZE - 9, pos, RULER_SIZE);
00238 
00239             if (s2 && start % st2 == 0)
00240                 p.drawLine(pos, RULER_SIZE - 7, pos, RULER_SIZE);
00241 
00242             if (s1 && start % st1 == 0)
00243                 p.drawLine(pos, RULER_SIZE - 5, pos, RULER_SIZE);
00244 
00245             if (step && start % step == 0) {
00246                 buf.setNum(QABS(start));
00247                 drawNums(&p, pos, 4, buf, true);
00248             }
00249 
00250             start++;
00251         } while (pos < m_pixmapBuffer -> width());
00252     } else {
00253         m_firstVisible = 0;
00254         float cx = KoUnit::fromUserValue(100, m_unit) / m_zoom;
00255         Q_INT32 height = m_pixmapBuffer -> height() - 1;
00256         Q_INT32 step = qRound(cx);
00257         Q_INT32 start = (Q_INT32)(KoUnit::toUserValue(m_firstVisible, m_unit) / m_zoom);
00258 
00259         do {
00260             pos = height - (Q_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible);
00261 
00262             if (!s3 && s4 && start % st4 == 0)
00263                 p.drawLine(RULER_SIZE - 9, pos, RULER_SIZE, pos);
00264 
00265             if (s3 && start % st3 == 0)
00266                 p.drawLine(RULER_SIZE - 9, pos, RULER_SIZE, pos);
00267 
00268             if (s2 && start % st2 == 0)
00269                 p.drawLine(RULER_SIZE - 7, pos, RULER_SIZE, pos);
00270 
00271             if (s1 && start % st1 == 0)
00272                 p.drawLine(RULER_SIZE - 5, pos, RULER_SIZE, pos);
00273 
00274             if (step && start % step == 0) {
00275                 buf.setNum(QABS(start));
00276                 drawNums(&p, 4, pos, buf, false);
00277             }
00278 
00279             start++;
00280         } while (pos > 0);
00281     }
00282 
00283     p.end();
00284 }
00285 
00286 void VRuler::resizeEvent(QResizeEvent *)
00287 {
00288     recalculateSize();
00289 }
00290 
00291 void VRuler::show()
00292 {
00293     if (m_orientation == Qt::Horizontal) {
00294         setFixedHeight(RULER_SIZE);
00295         initMarker(MARKER_WIDTH, MARKER_HEIGHT);
00296     } else {
00297         setFixedWidth(RULER_SIZE);
00298         initMarker(MARKER_HEIGHT, MARKER_WIDTH);
00299     }
00300 
00301     super::show();
00302 }
00303 
00304 void VRuler::hide()
00305 {
00306     if (m_orientation == Qt::Horizontal)
00307         setFixedHeight(1);
00308     else
00309         setFixedWidth(1);
00310 }
00311 
00312 void VRuler::drawNums(QPainter *p, Q_INT32 x, Q_INT32 y, QString& num, bool orientationHoriz)
00313 {
00314     if (orientationHoriz)
00315         x -= 7;
00316     else
00317         y -= 8;
00318 
00319     for (Q_UINT32 k = 0; k < num.length(); k++) {
00320         Q_INT32 st = num.at(k).digitValue() * 7;
00321 
00322         p -> drawPixmap(x, y, m_pixmapNums, st, 0, 7, 7);
00323 
00324         if (orientationHoriz)
00325             x += 7;
00326         else
00327             y += 8;
00328     }
00329 }
00330 
00331 #include "vruler.moc"
00332 
KDE Home | KDE Accessibility Home | Description of Access Keys