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