]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QBrowseBox.C
Minipage is no more (long live the box inset)
[lyx.git] / src / frontends / qt2 / QBrowseBox.C
1 /**
2  * \file QBrowseBox.C
3  *
4  * Original file taken from klyx 0.10 sources:
5  *
6  * \author Kalle Dalheimer
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include <qpixmap.h>
14 #include <qpainter.h>
15 #include <qapplication.h>
16 #include <qdrawutil.h>
17 #include <qstyle.h>
18
19 #include "QBrowseBox.h"
20
21 #include <cmath>
22
23
24 QBrowseBox::QBrowseBox(int rows, int cols, QWidget* parent, const char * name, WFlags f)
25         : QGridView(parent,name,f)
26 {
27         setNumRows(rows);
28         setNumCols(cols);
29
30         pixmaps_ = new QPixmap[rows * cols];
31
32         activecell_.setX(-1);
33         activecell_.setY(-1);
34
35         if (style().inherits("QWindowsStyle"))
36                 setFrameStyle(QFrame::WinPanel | QFrame::Raised);
37         else
38                 setFrameStyle(QFrame::Panel | QFrame::Raised);
39
40         setVScrollBarMode(QScrollView::AlwaysOff);
41         setHScrollBarMode(QScrollView::AlwaysOff);
42
43         viewport()->setFocusPolicy(QWidget::StrongFocus);
44         // setMouseTracking must be called after setFocusPolicy
45         viewport()->setMouseTracking(true);
46         inloop=false;
47
48 }
49
50
51 QBrowseBox::~QBrowseBox()
52 {
53         delete [] pixmaps_;
54 }
55
56
57 int QBrowseBox::coordsToIndex(int row, int col)
58 {
59         if (col < 0 || col > numCols() || row < 0 ||  row > numRows())
60                 qDebug("coordsToIndex: invalid coords (%d, %d)\n", row, col);
61         return row + col * numCols();
62 }
63
64
65 void QBrowseBox::insertItem(QPixmap pixmap, int row, int col)
66 {
67         pixmaps_[coordsToIndex(row, col)] = pixmap;
68 }
69
70
71 void QBrowseBox::insertItem(QPixmap pixmap)
72 {
73         int w = pixmap.width() / numCols();
74         int h = pixmap.height() / numRows();
75
76         for (int row = 0; row < numRows(); ++row) {
77                 for (int col = 0; col < numCols(); ++col) {
78                         QPixmap small(w,h);
79                         small.fill(backgroundColor());
80                         bitBlt(&small, 0, 0, &pixmap, col * w, row * h,
81                                 w, h, Qt::CopyROP, false);
82                         insertItem(small, row, col);
83                 }
84         }
85
86         setCellWidth(pixmap.width() / numCols());
87         setCellHeight(pixmap.height() / numRows());
88         setMinimumWidth(pixmap.width() + (numCols() + 1) * 1);
89         setMinimumHeight(pixmap.height() + (numRows() + 1) * 1);
90         resize(minimumSize());
91 }
92
93
94 QPixmap QBrowseBox::pixmap(int row, int col)
95 {
96         if (col < 0 || col >= numCols() || row < 0 || row >= numRows())
97                 return QPixmap();
98         return pixmaps_[coordsToIndex(row, col)];
99 }
100
101
102 int QBrowseBox::exec(const QPoint & pos)
103 {
104         return exec(pos.x(),pos.y());
105 }
106
107
108 int QBrowseBox::exec(const QWidget * trigger)
109 {
110         QPoint globalpos = trigger->parentWidget()->mapToGlobal( trigger->pos());
111         // is there enough space to put the box below the trigger?
112         if ( globalpos.y() + trigger->height()+height()+1<
113              QApplication::desktop()->height()) {
114                 // is there enough space to set the box left-justified with the trigger
115                 if (globalpos.x()+width()<QApplication::desktop()->width())
116                         return exec(globalpos.x(),
117                                     globalpos.y()+trigger->height()+1);
118                 else
119                         return exec(globalpos.x()-width()-1,
120                                     globalpos.y()+trigger->height()+1);
121         } else {
122                 if (globalpos.x()+width()<QApplication::desktop()->width())
123                         return exec(globalpos.x(),
124                                     globalpos.y()-height()-1);
125                 else
126                         return exec(globalpos.x()-width()-1,
127                                     globalpos.y()-height()-1);
128         }
129 }
130
131
132 int QBrowseBox::exec(int x,int y)
133 {
134         firstrelease_ = true;
135         move(x,y);
136         show();
137         repaint();
138         qApp->enter_loop();
139         inloop = true;
140
141         if (activecell_.x()!=-1 && activecell_.y()!=-1 )
142                 return coordsToIndex( activecell_.x(),activecell_.y());
143         else
144                 return -1;
145 }
146
147
148 void QBrowseBox::keyPressEvent(QKeyEvent * e)
149 {
150         switch(e->key()) {
151         case Key_Up:
152                 moveUp();
153                 break;
154         case Key_Down:
155                 moveDown();
156                 break;
157         case Key_Left:
158                 moveLeft();
159                 break;
160         case Key_Right:
161                 moveRight();
162                 break;
163         case Key_Return:
164                 emit selected(activecell_.x(), activecell_.y());
165                 if ( isVisible() && parentWidget() &&
166                      parentWidget()->inherits("QPopupMenu") )
167                         parentWidget()->close();
168                 else
169                         close();
170                 break;
171         case Key_Escape:
172                 if (inloop)
173                         qApp->exit_loop();
174                 if ( isVisible() && parentWidget() &&
175                      parentWidget()->inherits("QPopupMenu") )
176                         parentWidget()->close();
177         default:
178                 e->ignore();
179         }
180 }
181
182
183 void QBrowseBox::contentsMouseReleaseEvent(QMouseEvent *)
184 {
185
186         if (firstrelease_)
187                 firstrelease_ = false;
188         else {
189                 emit selected( activecell_.x(), activecell_.y());
190                 if ( isVisible() && parentWidget() &&
191                      parentWidget()->inherits("QPopupMenu") )
192                         parentWidget()->close();
193         }
194 }
195
196
197 void QBrowseBox::closeEvent(QCloseEvent * e)
198 {
199         e->accept();
200         qApp->exit_loop();
201 }
202
203
204 void QBrowseBox::paintCell(QPainter * painter, int row, int col)
205 {
206         painter->setClipRect(cellGeometry(row, col));
207
208         int const index = coordsToIndex(row, col);
209
210         painter->drawPixmap(0, 0, pixmaps_[index]);
211
212         if (activecell_.x() == row && activecell_.y() == col) {
213                 qDrawShadeRect(painter, 0, 0, cellWidth(),
214                                cellHeight(), colorGroup(), false, 1);
215         } else {
216                 qDrawPlainRect(painter, 0, 0, cellWidth(),
217                                cellHeight(), colorGroup().background(), 1);
218         }
219
220         painter->setClipping(false);
221 }
222
223
224 void QBrowseBox::contentsMouseMoveEvent(QMouseEvent * e)
225 {
226         int x = e->pos().x();
227         int y = e->pos().y();
228
229         int cellx;
230         int celly;
231
232         if (x < 0 || y < 0 || x > width() || y > height()) {
233                 // outside the box
234                 cellx = -1;
235                 celly = -1;
236         } else {
237                 celly = (int)floor( ((double)x) / ((double)cellWidth()) );
238                 cellx = (int)floor( ((double)y) / ((double)cellHeight()) );
239         }
240
241         if (activecell_.x() != cellx || activecell_.y() != celly) {
242                 // mouse has been moved to another cell
243                 int oldactivecellx = activecell_.x();
244                 int oldactivecelly = activecell_.y();
245                 activecell_.setX(cellx);
246                 activecell_.setY(celly);
247                 // remove old highlighting
248                 updateCell(oldactivecellx, oldactivecelly);
249                 // set new highlighting
250                 updateCell(activecell_.x(), activecell_.y());
251         }
252 }
253
254
255 void QBrowseBox::moveLeft()
256 {
257         int const y = activecell_.y();
258
259         if (y>0)
260                 activecell_.setY(y - 1);
261         else if (parentWidget())
262                 QWidget::focusNextPrevChild(false);
263
264         updateCell(activecell_.x(), y);
265         updateCell(activecell_.x(), activecell_.y());
266 }
267
268
269 void QBrowseBox::moveRight()
270 {
271         int const y = activecell_.y();
272
273         if (y < numCols() - 1)
274                 activecell_.setY(y+1);
275
276         updateCell(activecell_.x(), y);
277         updateCell(activecell_.x(), activecell_.y());
278 }
279
280
281 void QBrowseBox::moveUp()
282 {
283         int const x = activecell_.x();
284
285         if (x > 0)
286                 activecell_.setX(x - 1);
287         else if (parentWidget())
288                 QWidget::focusNextPrevChild(false);
289
290         updateCell(x, activecell_.y());
291         updateCell(activecell_.x(), activecell_.y());
292 }
293
294
295 void QBrowseBox::moveDown()
296 {
297         int const x = activecell_.x();
298
299         if (x < numRows() - 1)
300                 activecell_.setX(x + 1);
301
302         updateCell(x, activecell_.y());
303         updateCell(activecell_.x(), activecell_.y());
304 }