/* * Copyright © 2003-2007 Fredrik Höglund * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. * * 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; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include "previewwidget.h" #include "cursortheme.h" // Preview cursors const char * const cursor_names[] = { "left_ptr", "left_ptr_watch", "wait", "pointing_hand", "whats_this", "ibeam", "size_all", "size_fdiag", "cross", "split_h", "size_ver", "size_hor", "size_bdiag", "split_v", }; const int numCursors = 9; // The number of cursors from the above list to be previewed const int cursorSpacing = 20; // Spacing between preview cursors const int widgetMinWidth = 10; // The minimum width of the preview widget const int widgetMinHeight = 48; // The minimum height of the preview widget class PreviewCursor { public: PreviewCursor( const CursorTheme *theme, const QString &name, int size ); ~PreviewCursor() {} const QCursor &cursor() const { return m_cursor; } const QPixmap &pixmap() const { return m_pixmap; } int width() const { return m_pixmap.width(); } int height() const { return m_pixmap.height(); } inline QRect rect() const; void setPosition( const QPoint &p ) { m_pos = p; } void setPosition( int x, int y ) { m_pos = QPoint(x, y); } QPoint position() const { return m_pos; } private: QPixmap m_pixmap; QCursor m_cursor; QPoint m_pos; }; PreviewCursor::PreviewCursor(const CursorTheme *theme, const QString &name, int size) { // Create the preview pixmap QImage image = theme->loadImage(name, size); if (image.isNull()) return; m_pixmap = QPixmap::fromImage(image); // Load the cursor m_cursor = theme->loadCursor(name, size); // ### perhaps we should tag the cursor so it doesn't get // replaced when a new theme is applied } QRect PreviewCursor::rect() const { return QRect(m_pos, m_pixmap.size()) .adjusted(-(cursorSpacing / 2), -(cursorSpacing / 2), cursorSpacing / 2, cursorSpacing / 2); } // ------------------------------------------------------------------------------ PreviewWidget::PreviewWidget(QWidget *parent) : QWidget(parent) { setMouseTracking(true); current = NULL; } PreviewWidget::~PreviewWidget() { qDeleteAll(list); list.clear(); } QSize PreviewWidget::sizeHint() const { int totalWidth = 0; int maxHeight = 0; foreach (const PreviewCursor *c, list) { totalWidth += c->width(); maxHeight = qMax(c->height(), maxHeight); } totalWidth += (list.count() - 1) * cursorSpacing; maxHeight = qMax(maxHeight, widgetMinHeight); return QSize(qMax(totalWidth, widgetMinWidth), qMax(height(), maxHeight)); } void PreviewWidget::layoutItems() { if (!list.isEmpty()) { QSize size = sizeHint(); int cursorWidth = size.width() / list.count(); int nextX = (width() - size.width()) / 2; foreach (PreviewCursor *c, list) { c->setPosition(nextX + (cursorWidth - c->width()) / 2, (height() - c->height()) / 2); nextX += cursorWidth; } } needLayout = false; } void PreviewWidget::setTheme(const CursorTheme *theme, const int size) { qDeleteAll(list); list.clear(); if (theme) { for (int i = 0; i < numCursors; i++) list << new PreviewCursor(theme, cursor_names[i], size); needLayout = true; updateGeometry(); } current = NULL; update(); } void PreviewWidget::paintEvent(QPaintEvent *) { QPainter p(this); if (needLayout) layoutItems(); foreach(const PreviewCursor *c, list) { if (c->pixmap().isNull()) continue; p.drawPixmap(c->position(), c->pixmap()); } } void PreviewWidget::mouseMoveEvent(QMouseEvent *e) { if (needLayout) layoutItems(); foreach (const PreviewCursor *c, list) { if (c->rect().contains(e->pos())) { if (c != current) { setCursor(c->cursor()); current = c; } return; } } setCursor(Qt::ArrowCursor); current = NULL; } void PreviewWidget::resizeEvent(QResizeEvent *) { if (!list.isEmpty()) needLayout = true; }