mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 10:52:51 +00:00
229 lines
5.3 KiB
C++
229 lines
5.3 KiB
C++
/*
|
|
* Copyright © 2003-2007 Fredrik Höglund <fredrik@kde.org>
|
|
*
|
|
* 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 <QPainter>
|
|
#include <QtGui/qevent.h>
|
|
|
|
#include "previewwidget.h"
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xcursor/Xcursor.h>
|
|
|
|
#include "cursortheme.h"
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// 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 QPixmap &pixmap() const { return m_pixmap; }
|
|
Cursor handle() const { return m_cursor.handle(); }
|
|
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; }
|
|
operator const QCursor& () const { return m_cursor; }
|
|
operator const QPixmap& () const { return pixmap(); }
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
void PreviewWidget::mouseMoveEvent(QMouseEvent *e)
|
|
{
|
|
if (needLayout)
|
|
layoutItems();
|
|
|
|
foreach (const PreviewCursor *c, list)
|
|
{
|
|
if (c->rect().contains(e->pos()))
|
|
{
|
|
if (c != current)
|
|
{
|
|
setCursor(*c);
|
|
current = c;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
setCursor(Qt::ArrowCursor);
|
|
current = NULL;
|
|
}
|
|
|
|
|
|
void PreviewWidget::resizeEvent(QResizeEvent *)
|
|
{
|
|
if (!list.isEmpty())
|
|
needLayout = true;
|
|
}
|
|
|