diff options
Diffstat (limited to 'kalzium/src/kalziumtip.cpp')
-rw-r--r-- | kalzium/src/kalziumtip.cpp | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/kalzium/src/kalziumtip.cpp b/kalzium/src/kalziumtip.cpp new file mode 100644 index 00000000..0f053c77 --- /dev/null +++ b/kalzium/src/kalziumtip.cpp @@ -0,0 +1,306 @@ +/*************************************************************************** + * Copyright (C) 2005 by Zack Rusin <zrusin@kde.org> * + * Sami Kyostil <skyostil@kempele.fi> * + * Aaron J. Seigo <aseigo@kde.org> * + * Martin Pfeiffer <hubipete@gmx.net> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "kalziumtip.h" +#include "kalziumutils.h" +#include "element.h" + +#include <qapplication.h> +#include <qpixmap.h> +#include <qimage.h> +#include <qsimplerichtext.h> +#include <qpainter.h> +#include <qdesktopwidget.h> + +#include <kdialog.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kstandarddirs.h> + +KalziumTip::KalziumTip( QWidget * parent, const char * name, WFlags f ) : QWidget( parent, name, f ) +{ + setFocusPolicy(NoFocus); //the widget don't get the keyboard focus + setBackgroundMode(NoBackground); // widget has no background + resize(0,0); + hide(); //initailly hide it + m_richText = 0; + m_noElemIcon = KGlobal::iconLoader()->loadIcon( "orbits", KIcon::NoGroup, 64 ); + setMouseTracking(true); // receice mouse move events + + connect(&m_frameTimer, SIGNAL(timeout()), SLOT(internalUpdate())); +} + +void KalziumTip::showTip( QPoint mouse, Element* element, int visibleWidth, int visibleHeight ) +{ + QWidget *p = 0; + if ( dynamic_cast<QWidget*>( parent() ) ) + p = static_cast<QWidget*>( parent() ); + + if ( p ) + { + if ( mouse.y() + size().height() > visibleHeight ) + mouse.setY( mouse.y() - size().height() ); + if ( mouse.x() + size().width() > visibleWidth ) + mouse.setX( mouse.x() - size().width() ); + + if ( p->width() < visibleWidth ) + { + if ( mouse.x() + size().width() > p->width() ) + mouse.setX( mouse.x() - size().width() ); + } + + if ( p->height() < visibleHeight ) + { + if ( mouse.y() + size().height() > p->height() ) + mouse.setY( mouse.y() - size().height() ); + } + } + + m_mousePointer = mouse; + + if( element == m_tippedElement ) + { + // Avoid moving out of the current screen + if (m_mousePointer.x()+width() > qApp->desktop()->width()) + m_mousePointer.setX(qApp->desktop()->width() - width()); + + move(m_mousePointer); //do not paint again if already painted + } + else + { + if ( element == 0) + return; + + m_tippedElement = element; + + loadIcon(); //load icon + display(); + } +} + +void KalziumTip::paintEvent(QPaintEvent* e) +{ + if (m_dirty) + { + displayInternal(); + m_dirty = false; + } + + QPainter p(this); + p.drawPixmap(e->rect().topLeft(), m_pixmap, e->rect()); +} + +void KalziumTip::mouseMoveEvent(QMouseEvent * e) +{ + // delegate the mouse move event to the parent (actually the elements table) + // so that this tooltip doesn't stop to be updated + e->ignore(); +} + +void KalziumTip::display() +{ + if( !m_tippedElement ) + return; + + delete m_richText; + + QString elementname = m_tippedElement->elname(); + + QString number = i18n( "Number: %1" ) + .arg( QString::number(m_tippedElement->number()) ); + + QString mass = i18n( "Mass: %1" ) + .arg( KalziumUtils::localizedValue(m_tippedElement->mass(), 6) ); + + m_richText = new QSimpleRichText("<qt><h1>" + elementname + "</h1><p>" + + number + "</p><p>" + + mass +"</p></qt>", font()); + + m_richText->setWidth(400); + + m_maskEffect = isVisible() ? Plain : Dissolve; + m_dissolveSize = 24; + m_dissolveDelta = -1; + + displayInternal(); + m_frameTimer.start(500/30); + + move(m_mousePointer); + show(); +} + +void KalziumTip::displayInternal() +{ + if (!m_richText) + return; + + + // determine text rectangel sizes + QRect textRect(0,0,0,0); + textRect.setWidth(m_richText->widthUsed()); + textRect.setHeight(m_richText->height()); + + //moves the rect + textRect.moveBy(-textRect.left(), -textRect.top()); + // add the new coordinates + textRect.addCoords(0,0,2,2); + + int margin = KDialog::marginHint(); + int height = QMAX(m_icon.height(), textRect.height()) + 2 * margin; + int textX = 2 + m_icon.width() + 2 * margin; + int width = textX + textRect.width() + margin; + int textY = (height - textRect.height()) / 2; + + //resize pixmap, mask and widget + m_mask.resize(width, height); + m_pixmap.resize(width, height); + resize(width, height); + + // create and set transparency mask + switch(m_maskEffect) + { + case Plain: + plainMask(); + break; + + case Dissolve: + dissolveMask(); + break; + } + + // draw background + QPainter bufferPainter(&m_pixmap); + bufferPainter.setPen(Qt::black); + bufferPainter.setBrush(backgroundColor()); + bufferPainter.drawRoundRect(0, 0, width, height, + 1600 / width, 1600 / height); + + // draw icon if present + if (!m_icon.isNull()) + { + bufferPainter.drawPixmap(margin, + margin, + m_icon, 0, 0, + m_icon.width(), m_icon.height()); + } + + // draw text shadow + QColorGroup cg = colorGroup(); + cg.setColor(QColorGroup::Text, cg.background().dark(115)); + int shadowOffset = QApplication::reverseLayout() ? -1 : 1; + m_richText->draw(&bufferPainter, 5 + textX + shadowOffset, textY + 1, QRect(), cg); + + // draw text + cg = colorGroup(); + m_richText->draw(&bufferPainter, 5 + textX, textY, rect(), cg); +} + +void KalziumTip::dissolveMask() +{ + QPainter maskPainter(&m_mask); + + m_mask.fill(Qt::black); + + maskPainter.setBrush(Qt::white); + maskPainter.setPen(Qt::white); + maskPainter.drawRoundRect(m_mask.rect(), 1600 / m_mask.rect().width(), + 1600 / m_mask.rect().height()); + + m_dissolveSize += m_dissolveDelta; + + if (m_dissolveSize > 0) + { + maskPainter.setRasterOp(Qt::EraseROP); + + int x, y, s; + const int size = 16; + const int heightsize = size + height(); + + for (y = 0; y < heightsize; y += size) + { + x = width(); + s = m_dissolveSize * x / 128; + for (; x > -size; x -= size, s -= 2) + { + if (s < 0) + { + s = 0; + } + maskPainter.drawEllipse(x - s / 2, y - s / 2, s, s); + } + } + } + else if (m_dissolveSize < 0) + { + m_frameTimer.stop(); + m_dissolveDelta = 1; + } + + setMask(m_mask); +} + +void KalziumTip::hide() +{ + m_frameTimer.stop(); + m_tippedElement = 0; + QWidget::hide(); +} + +void KalziumTip::plainMask() +{ + QPainter maskPainter(&m_mask); + + m_mask.fill(Qt::black); + + maskPainter.setBrush(Qt::white); + maskPainter.setPen(Qt::white); + maskPainter.drawRoundRect(m_mask.rect(), 1600 / m_mask.rect().width(), + 1600 / m_mask.rect().height()); + setMask(m_mask); + m_frameTimer.stop(); +} + +void KalziumTip::internalUpdate() +{ + m_dirty = true; + update(); +} + +void KalziumTip::loadIcon() +{ + QString iconpath = locate( "data" , "kalzium/elempics/" + m_tippedElement->symbol() + ".jpg" ); + if ( !iconpath.isEmpty() ) + { + QImage img ( iconpath, "JPEG" ); + img = img.smoothScale ( 128, 128, QImage::ScaleMin ); + m_icon.convertFromImage( img ); + + } + else + { + m_icon = m_noElemIcon; + } +} + +#include "kalziumtip.moc" |