mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-11 13:46:43 +00:00
309 lines
6.4 KiB
C++
309 lines
6.4 KiB
C++
|
/**
|
||
|
* \file QBrowseBox.C
|
||
|
*
|
||
|
* Original file taken from klyx 0.10 sources:
|
||
|
*
|
||
|
* \author Kalle Dalheimer
|
||
|
*
|
||
|
* Full author contact details are available in file CREDITS.
|
||
|
*/
|
||
|
|
||
|
#include <config.h>
|
||
|
|
||
|
#include "QBrowseBox.h"
|
||
|
|
||
|
#include <QPixmap>
|
||
|
#include <QPainter>
|
||
|
#include <QApplication>
|
||
|
#include <qdrawutil.h>
|
||
|
#include <QStyle>
|
||
|
#include <QMouseEvent>
|
||
|
#include <QFrame>
|
||
|
#include <QKeyEvent>
|
||
|
#include <QCloseEvent>
|
||
|
|
||
|
#include <QDesktopWidget>
|
||
|
|
||
|
#include <cmath>
|
||
|
|
||
|
|
||
|
QBrowseBox::QBrowseBox(int rows, int cols, QWidget* parent, const char * name, Qt::WFlags f)
|
||
|
: Q3GridView(parent,name,f)
|
||
|
{
|
||
|
setNumRows(rows);
|
||
|
setNumCols(cols);
|
||
|
|
||
|
pixmaps_ = new QPixmap[rows * cols];
|
||
|
|
||
|
activecell_.setX(-1);
|
||
|
activecell_.setY(-1);
|
||
|
|
||
|
|
||
|
setFrameStyle(QFrame::WinPanel | QFrame::Raised);
|
||
|
|
||
|
setVScrollBarMode(Q3ScrollView::AlwaysOff);
|
||
|
setHScrollBarMode(Q3ScrollView::AlwaysOff);
|
||
|
|
||
|
viewport()->setFocusPolicy(Qt::StrongFocus);
|
||
|
// setMouseTracking must be called after setFocusPolicy
|
||
|
viewport()->setMouseTracking(true);
|
||
|
inloop=false;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
QBrowseBox::~QBrowseBox()
|
||
|
{
|
||
|
delete [] pixmaps_;
|
||
|
}
|
||
|
|
||
|
|
||
|
int QBrowseBox::coordsToIndex(int row, int col)
|
||
|
{
|
||
|
if (col < 0 || col > numCols() || row < 0 || row > numRows())
|
||
|
qDebug("coordsToIndex: invalid coords (%d, %d)\n", row, col);
|
||
|
return row + col * numCols();
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::insertItem(QPixmap pixmap, int row, int col)
|
||
|
{
|
||
|
pixmaps_[coordsToIndex(row, col)] = pixmap;
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::insertItem(QPixmap pixmap)
|
||
|
{
|
||
|
int w = pixmap.width() / numCols();
|
||
|
int h = pixmap.height() / numRows();
|
||
|
|
||
|
for (int row = 0; row < numRows(); ++row) {
|
||
|
for (int col = 0; col < numCols(); ++col) {
|
||
|
QPixmap small(w,h);
|
||
|
small.fill(backgroundColor());
|
||
|
bitBlt(&small, 0, 0, &pixmap, col * w, row * h,
|
||
|
w, h);
|
||
|
insertItem(small, row, col);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
setCellWidth(pixmap.width() / numCols());
|
||
|
setCellHeight(pixmap.height() / numRows());
|
||
|
setMinimumWidth(pixmap.width() + (numCols() + 1) * 1);
|
||
|
setMinimumHeight(pixmap.height() + (numRows() + 1) * 1);
|
||
|
resize(minimumSize());
|
||
|
}
|
||
|
|
||
|
|
||
|
QPixmap QBrowseBox::pixmap(int row, int col)
|
||
|
{
|
||
|
if (col < 0 || col >= numCols() || row < 0 || row >= numRows())
|
||
|
return QPixmap();
|
||
|
return pixmaps_[coordsToIndex(row, col)];
|
||
|
}
|
||
|
|
||
|
|
||
|
int QBrowseBox::exec(const QPoint & pos)
|
||
|
{
|
||
|
return exec(pos.x(),pos.y());
|
||
|
}
|
||
|
|
||
|
|
||
|
int QBrowseBox::exec(const QWidget * trigger)
|
||
|
{
|
||
|
QPoint globalpos = trigger->parentWidget()->mapToGlobal( trigger->pos());
|
||
|
// is there enough space to put the box below the trigger?
|
||
|
if ( globalpos.y() + trigger->height()+height()+1<
|
||
|
QApplication::desktop()->height()) {
|
||
|
// is there enough space to set the box left-justified with the trigger
|
||
|
if (globalpos.x()+width()<QApplication::desktop()->width())
|
||
|
return exec(globalpos.x(),
|
||
|
globalpos.y()+trigger->height()+1);
|
||
|
else
|
||
|
return exec(globalpos.x()-width()-1,
|
||
|
globalpos.y()+trigger->height()+1);
|
||
|
} else {
|
||
|
if (globalpos.x()+width()<QApplication::desktop()->width())
|
||
|
return exec(globalpos.x(),
|
||
|
globalpos.y()-height()-1);
|
||
|
else
|
||
|
return exec(globalpos.x()-width()-1,
|
||
|
globalpos.y()-height()-1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
int QBrowseBox::exec(int x,int y)
|
||
|
{
|
||
|
firstrelease_ = true;
|
||
|
move(x,y);
|
||
|
show();
|
||
|
update();
|
||
|
qApp->enter_loop();
|
||
|
inloop = true;
|
||
|
|
||
|
if (activecell_.x()!=-1 && activecell_.y()!=-1 )
|
||
|
return coordsToIndex( activecell_.x(),activecell_.y());
|
||
|
else
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::keyPressEvent(QKeyEvent * e)
|
||
|
{
|
||
|
switch(e->key()) {
|
||
|
case Qt::Key_Up:
|
||
|
moveUp();
|
||
|
break;
|
||
|
case Qt::Key_Down:
|
||
|
moveDown();
|
||
|
break;
|
||
|
case Qt::Key_Left:
|
||
|
moveLeft();
|
||
|
break;
|
||
|
case Qt::Key_Right:
|
||
|
moveRight();
|
||
|
break;
|
||
|
case Qt::Key_Return:
|
||
|
emit selected(activecell_.x(), activecell_.y());
|
||
|
if ( isVisible() && parentWidget() &&
|
||
|
parentWidget()->inherits("QPopupMenu") )
|
||
|
parentWidget()->close();
|
||
|
else
|
||
|
close();
|
||
|
break;
|
||
|
case Qt::Key_Escape:
|
||
|
if (inloop)
|
||
|
qApp->exit_loop();
|
||
|
if ( isVisible() && parentWidget() &&
|
||
|
parentWidget()->inherits("QPopupMenu") )
|
||
|
parentWidget()->close();
|
||
|
default:
|
||
|
e->ignore();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::contentsMouseReleaseEvent(QMouseEvent *)
|
||
|
{
|
||
|
|
||
|
if (firstrelease_)
|
||
|
firstrelease_ = false;
|
||
|
else {
|
||
|
emit selected( activecell_.x(), activecell_.y());
|
||
|
if ( isVisible() && parentWidget() &&
|
||
|
parentWidget()->inherits("QPopupMenu") )
|
||
|
parentWidget()->close();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::closeEvent(QCloseEvent * e)
|
||
|
{
|
||
|
e->accept();
|
||
|
qApp->exit_loop();
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::paintCell(QPainter * painter, int row, int col)
|
||
|
{
|
||
|
painter->setClipRect(cellGeometry(row, col));
|
||
|
|
||
|
int const index = coordsToIndex(row, col);
|
||
|
|
||
|
painter->drawPixmap(0, 0, pixmaps_[index]);
|
||
|
|
||
|
if (activecell_.x() == row && activecell_.y() == col) {
|
||
|
qDrawShadeRect(painter, 0, 0, cellWidth(),
|
||
|
cellHeight(), colorGroup(), false, 1);
|
||
|
} else {
|
||
|
qDrawPlainRect(painter, 0, 0, cellWidth(),
|
||
|
cellHeight(), colorGroup().background(), 1);
|
||
|
}
|
||
|
|
||
|
painter->setClipping(false);
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::contentsMouseMoveEvent(QMouseEvent * e)
|
||
|
{
|
||
|
int x = e->pos().x();
|
||
|
int y = e->pos().y();
|
||
|
|
||
|
int cellx;
|
||
|
int celly;
|
||
|
|
||
|
if (x < 0 || y < 0 || x > width() || y > height()) {
|
||
|
// outside the box
|
||
|
cellx = -1;
|
||
|
celly = -1;
|
||
|
} else {
|
||
|
celly = (int)floor( ((double)x) / ((double)cellWidth()) );
|
||
|
cellx = (int)floor( ((double)y) / ((double)cellHeight()) );
|
||
|
}
|
||
|
|
||
|
if (activecell_.x() != cellx || activecell_.y() != celly) {
|
||
|
// mouse has been moved to another cell
|
||
|
int oldactivecellx = activecell_.x();
|
||
|
int oldactivecelly = activecell_.y();
|
||
|
activecell_.setX(cellx);
|
||
|
activecell_.setY(celly);
|
||
|
// remove old highlighting
|
||
|
updateCell(oldactivecellx, oldactivecelly);
|
||
|
// set new highlighting
|
||
|
updateCell(activecell_.x(), activecell_.y());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::moveLeft()
|
||
|
{
|
||
|
int const y = activecell_.y();
|
||
|
|
||
|
if (y>0)
|
||
|
activecell_.setY(y - 1);
|
||
|
else if (parentWidget())
|
||
|
QWidget::focusNextPrevChild(false);
|
||
|
|
||
|
updateCell(activecell_.x(), y);
|
||
|
updateCell(activecell_.x(), activecell_.y());
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::moveRight()
|
||
|
{
|
||
|
int const y = activecell_.y();
|
||
|
|
||
|
if (y < numCols() - 1)
|
||
|
activecell_.setY(y+1);
|
||
|
|
||
|
updateCell(activecell_.x(), y);
|
||
|
updateCell(activecell_.x(), activecell_.y());
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::moveUp()
|
||
|
{
|
||
|
int const x = activecell_.x();
|
||
|
|
||
|
if (x > 0)
|
||
|
activecell_.setX(x - 1);
|
||
|
else if (parentWidget())
|
||
|
QWidget::focusNextPrevChild(false);
|
||
|
|
||
|
updateCell(x, activecell_.y());
|
||
|
updateCell(activecell_.x(), activecell_.y());
|
||
|
}
|
||
|
|
||
|
|
||
|
void QBrowseBox::moveDown()
|
||
|
{
|
||
|
int const x = activecell_.x();
|
||
|
|
||
|
if (x < numRows() - 1)
|
||
|
activecell_.setX(x + 1);
|
||
|
|
||
|
updateCell(x, activecell_.y());
|
||
|
updateCell(activecell_.x(), activecell_.y());
|
||
|
}
|