1 /*******************************************************************************
2 **
3 ** Photivo
4 **
5 ** Copyright (C) 2011 Bernd Schoeler <brjohn@brother-john.net>
6 **
7 ** This file is part of Photivo.
8 **
9 ** Photivo is free software: you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License version 3
11 ** as published by the Free Software Foundation.
12 **
13 ** Photivo is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with Photivo.  If not, see <http://www.gnu.org/licenses/>.
20 **
21 *******************************************************************************/
22 
23 #include "../ptSettings.h"
24 #include "ptColumnGridThumbnailLayouter.h"
25 
26 #include <qmath.h>
27 #include <QScrollBar>
28 #include <QKeyEvent>
29 
30 extern ptSettings* Settings;
31 
32 //==============================================================================
33 
ptColumnGridThumbnailLayouter(QGraphicsView * view)34 ptColumnGridThumbnailLayouter::ptColumnGridThumbnailLayouter(QGraphicsView* view)
35 : ptGridThumbnailLayouter(view)
36 {}
37 
38 //==============================================================================
39 
Init(const int thumbCount,const QFont & font)40 void ptColumnGridThumbnailLayouter::Init(const int thumbCount, const QFont& font) {
41   ptGridThumbnailLayouter::Init(thumbCount, font);
42 
43   // Add another padding to width to make the layout in rows visually clear.
44   m_ThumbMetrics.CellWidth += m_ThumbMetrics.Padding;
45 
46   // For detailed comments see ptRowGridThumbnailLayouter
47   int RestrictedMax = Settings->GetInt("FileMgrUseThumbMaxRowCol") == 0 ?
48                       INT_MAX-1 : Settings->GetInt("FileMgrThumbMaxRowCol")-1;
49   m_ThumbMetrics.MaxRow =
50       qMin(RestrictedMax,
51            (m_View->height() + m_ThumbMetrics.Padding) / m_ThumbMetrics.CellHeight - 1);
52 
53   int FullWidth = qCeil((qreal)thumbCount / (qreal)(m_ThumbMetrics.MaxRow + 1)) *
54                   m_ThumbMetrics.CellWidth;
55 
56   if (FullWidth >= m_View->width()) {
57     // we have enough thumbs to produce a vertical scrollbar
58     m_View->horizontalScrollBar()->setSingleStep(m_ThumbMetrics.CellWidth);
59 
60     if((m_View->height() - (m_ThumbMetrics.MaxRow + 1)*m_ThumbMetrics.CellHeight) <
61        m_View->horizontalScrollBar()->height())
62     { // empty space on the bottom is not tall enough for scrollbar
63       m_ThumbMetrics.MaxRow--;
64       FullWidth = qCeil((qreal)thumbCount / (qreal)(m_ThumbMetrics.MaxRow + 1)) *
65                    m_ThumbMetrics.CellWidth;
66     }
67   }
68 
69   m_View->scene()->setSceneRect(
70       0, 0,
71       FullWidth,
72       m_ThumbMetrics.CellHeight*(m_ThumbMetrics.MaxRow + 1) - m_ThumbMetrics.Padding);
73 }
74 
75 //==============================================================================
76 
Layout(ptGraphicsThumbGroup * thumb)77 void ptColumnGridThumbnailLayouter::Layout(ptGraphicsThumbGroup* thumb) {
78   if (m_LazyInit) {
79     m_LazyInit = false;
80     Init(m_ThumbCount, thumb->font());
81   }
82 
83   // The +1 y position accounts for the 2px wide mouse hover border.
84   // Without it that wouldn’t be shown completely on the first column.
85   thumb->setPos((m_ThumbMetrics.Col * m_ThumbMetrics.CellWidth) + 1,
86                 m_ThumbMetrics.Row * m_ThumbMetrics.CellHeight);
87 
88   if (m_ThumbMetrics.Row >= m_ThumbMetrics.MaxRow) {
89     m_ThumbMetrics.Row = 0;
90     m_ThumbMetrics.Col++;
91   } else {
92     m_ThumbMetrics.Row++;
93   }
94 }
95 
96 //==============================================================================
97 
MoveIndex(const int currentIdx,QKeyEvent * event)98 int ptColumnGridThumbnailLayouter::MoveIndex(const int currentIdx, QKeyEvent* event) {
99   // See .h for full documentation of behaviour
100   int idx = qMax(0, currentIdx);
101   int offset = idx % (m_ThumbMetrics.MaxRow+1);
102   if (event->modifiers() == Qt::NoModifier) {
103     switch (event->key()) {
104       case Qt::Key_Left:
105         if (idx > m_ThumbMetrics.MaxRow)
106           idx = idx - m_ThumbMetrics.MaxRow - 1;
107         return idx;
108       case Qt::Key_Right:
109         return qMin(m_ThumbCount-1, idx + m_ThumbMetrics.MaxRow + 1);
110       case Qt::Key_Up:
111         return qMax(0, idx-1);
112       case Qt::Key_Down:
113         return qMin(m_ThumbCount-1, idx+1);
114       case Qt::Key_Home:  // start of column
115         return qMax(0, idx - offset);
116       case Qt::Key_End:   // end of column
117         return qMin(m_ThumbCount-1, idx + m_ThumbMetrics.MaxRow - offset);
118       case Qt::Key_PageUp:
119         return
120             qMax(0 + offset,
121                  idx - (int)(m_View->width()/m_ThumbMetrics.CellWidth)*(m_ThumbMetrics.MaxRow+1));
122       case Qt::Key_PageDown:
123         return
124             qMin(m_ThumbCount-1,
125                  idx + (int)(m_View->width()/m_ThumbMetrics.CellWidth)*(m_ThumbMetrics.MaxRow+1));
126       default:    // unrecognised key
127         return -1;
128     }
129 
130   } else if (event->modifiers() == Qt::ControlModifier) {
131     switch (event->key()) {
132       case Qt::Key_Home: return 0;                // first thumbnail in list
133       case Qt::Key_End:  return m_ThumbCount-1;   // last thumbnail in list
134       default:           return -1;               // unrecognised key
135     }
136 
137   } else {
138     return -1;    // unrecognised key
139   }
140 }
141 
142 //==============================================================================
143