|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation. |
|
3 */ |
|
4 |
|
5 #include "qaspectratiolayout.h" |
|
6 |
|
7 QAspectRatioLayout::QAspectRatioLayout(QWidget* parent, int spacing) : QLayout(parent) { |
|
8 init(spacing); |
|
9 } |
|
10 |
|
11 QAspectRatioLayout::QAspectRatioLayout(int spacing) { |
|
12 init(spacing); |
|
13 } |
|
14 |
|
15 QAspectRatioLayout::~QAspectRatioLayout() { |
|
16 delete item; |
|
17 delete lastReceivedRect; |
|
18 delete _geometry; |
|
19 } |
|
20 |
|
21 void QAspectRatioLayout::init(int spacing) { |
|
22 item = 0; |
|
23 lastReceivedRect = new QRect(0, 0, 0, 0); |
|
24 _geometry = new QRect(0, 0, 0, 0); |
|
25 setSpacing(spacing); |
|
26 } |
|
27 |
|
28 |
|
29 /* Adds item if place isn't already taken. */ |
|
30 void QAspectRatioLayout::add(QLayoutItem* item) { |
|
31 if(!hasItem()) { |
|
32 replaceItem(item); |
|
33 } |
|
34 } |
|
35 |
|
36 /* Adds item if place isn't already taken. */ |
|
37 void QAspectRatioLayout::addItem(QLayoutItem* item) { |
|
38 if(!hasItem()) { |
|
39 replaceItem(item); |
|
40 } |
|
41 } |
|
42 |
|
43 /* Adds widget if place isn't already taken. */ |
|
44 void QAspectRatioLayout::addWidget(QWidget* widget) { |
|
45 if(!hasItem()) { |
|
46 replaceItem(new QWidgetItem(widget)); |
|
47 } |
|
48 } |
|
49 |
|
50 /* Returns the item pointer and dereferences it here. */ |
|
51 QLayoutItem* QAspectRatioLayout::take() { |
|
52 QLayoutItem* item = 0; |
|
53 if(this->hasItem()) { |
|
54 item = this->item; |
|
55 this->item = 0; |
|
56 } |
|
57 return item; |
|
58 } |
|
59 |
|
60 /* Returns the item pointer and dereferences it here. */ |
|
61 QLayoutItem* QAspectRatioLayout::takeAt(int index) { |
|
62 if(index != 0) { |
|
63 return 0; |
|
64 } |
|
65 return this->take(); |
|
66 } |
|
67 |
|
68 /* Returns the item pointer. */ |
|
69 QLayoutItem* QAspectRatioLayout::itemAt(int index) const { |
|
70 if(index != 0) { |
|
71 return 0; |
|
72 } |
|
73 if(hasItem()) { |
|
74 return this->item; |
|
75 } |
|
76 return 0; |
|
77 } |
|
78 |
|
79 /* Checks if we have an item. */ |
|
80 bool QAspectRatioLayout::hasItem() const { |
|
81 return this->item != 0; |
|
82 } |
|
83 |
|
84 /* Returns the count of items which can be either 0 or 1. */ |
|
85 int QAspectRatioLayout::count() const { |
|
86 int returnValue = 0; |
|
87 if(hasItem()) { |
|
88 returnValue = 1; |
|
89 } |
|
90 return returnValue; |
|
91 } |
|
92 |
|
93 /* Replaces the item with the new and returns the old. */ |
|
94 QLayoutItem* QAspectRatioLayout::replaceItem(QLayoutItem* item) { |
|
95 QLayoutItem* old = 0; |
|
96 if(this->hasItem()) { |
|
97 old = this->item; |
|
98 } |
|
99 this->item = item; |
|
100 setGeometry(*this->_geometry); |
|
101 return old; |
|
102 } |
|
103 |
|
104 /* Tells which way layout expands. */ |
|
105 Qt::Orientations QAspectRatioLayout::expandingDirections() const { |
|
106 return Qt::Horizontal | Qt::Vertical; |
|
107 } |
|
108 |
|
109 /* Tells which size is preferred. */ |
|
110 QSize QAspectRatioLayout::sizeHint() const { |
|
111 return this->item->minimumSize(); |
|
112 } |
|
113 |
|
114 /* Tells minimum size. */ |
|
115 QSize QAspectRatioLayout::minimumSize() const { |
|
116 return this->item->minimumSize(); |
|
117 } |
|
118 |
|
119 /* |
|
120 * Tells if heightForWidth calculations is handled. |
|
121 * It isn't since width isn't enough to calculate |
|
122 * proper size. |
|
123 */ |
|
124 bool QAspectRatioLayout::hasHeightForWidth() const { |
|
125 return false; |
|
126 } |
|
127 |
|
128 /* Replaces lastReceivedRect. */ |
|
129 void QAspectRatioLayout::setLastReceivedRect(const QRect& rect) { |
|
130 QRect* oldRect = this->lastReceivedRect; |
|
131 this->lastReceivedRect = new QRect(rect.topLeft(), rect.size()); |
|
132 delete oldRect; |
|
133 } |
|
134 |
|
135 /* Returns geometry */ |
|
136 QRect QAspectRatioLayout::geometry() { |
|
137 return QRect(*this->_geometry); |
|
138 } |
|
139 |
|
140 /* Sets geometry to given size. */ |
|
141 void QAspectRatioLayout::setGeometry(const QRect& rect) { |
|
142 /* |
|
143 * We check if the item is set and |
|
144 * if size is the same previously received. |
|
145 * If either is false nothing is done. |
|
146 */ |
|
147 if(!this->hasItem() || |
|
148 areRectsEqual(*this->lastReceivedRect, rect)) { |
|
149 return; |
|
150 } |
|
151 /* Replace the last received rectangle. */ |
|
152 setLastReceivedRect(rect); |
|
153 /* Calculate proper size for the item relative to the received size. */ |
|
154 QSize properSize = calculateProperSize(rect.size()); |
|
155 /* Calculate center location in the rect and with item size. */ |
|
156 QPoint properLocation = calculateCenterLocation(rect.size(), properSize); |
|
157 /* Set items geometry */ |
|
158 this->item->setGeometry(QRect(properLocation, properSize)); |
|
159 QRect* oldRect = this->_geometry; |
|
160 /* Cache the calculated geometry. */ |
|
161 this->_geometry = new QRect(properLocation, properSize); |
|
162 delete oldRect; |
|
163 /* Super classes setGeometry */ |
|
164 QLayout::setGeometry(*this->_geometry); |
|
165 } |
|
166 |
|
167 /* Takes the shortest side and creates QSize |
|
168 * with the shortest side as width and height. */ |
|
169 QSize QAspectRatioLayout::calculateProperSize(QSize from) const { |
|
170 QSize properSize; |
|
171 if(from.height() * 2 < from.width()) { |
|
172 properSize.setHeight(from.height() - this->margin()); |
|
173 properSize.setWidth(from.height() * 2 - this->margin()); |
|
174 } |
|
175 else { |
|
176 properSize.setWidth(from.width() - this->margin()); |
|
177 properSize.setHeight(from.width() / 2 - this->margin()); |
|
178 } |
|
179 return properSize; |
|
180 } |
|
181 |
|
182 /* Calculates center location from the given height and width for item size. */ |
|
183 QPoint QAspectRatioLayout::calculateCenterLocation(QSize from, |
|
184 QSize itemSize) const { |
|
185 QPoint centerLocation; |
|
186 if((from.width() - itemSize.width()) > 0) { |
|
187 centerLocation.setX((from.width() - itemSize.width())/2); |
|
188 } |
|
189 if((from.height() - itemSize.height()) > 0) { |
|
190 centerLocation.setY((from.height() - itemSize.height())/2); |
|
191 } |
|
192 return centerLocation; |
|
193 } |
|
194 |
|
195 /* Compares if two QRects are equal. */ |
|
196 bool QAspectRatioLayout::areRectsEqual(const QRect& a, |
|
197 const QRect& b) const { |
|
198 bool result = false; |
|
199 if(a.x() == b.x() && |
|
200 a.y() == b.y() && |
|
201 a.height() == b.height() && |
|
202 a.width() == b.width()) { |
|
203 result = true; |
|
204 } |
|
205 return result; |
|
206 } |