Merge lp:~fboucault/camera-app/resolution_options into lp:camera-app/staging
- resolution_options
- Merge into staging
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Florian Boucault | ||||
Approved revision: | 604 | ||||
Merged at revision: | 611 | ||||
Proposed branch: | lp:~fboucault/camera-app/resolution_options | ||||
Merge into: | lp:camera-app/staging | ||||
Diff against target: |
473 lines (+289/-19) 5 files modified
BottomEdgeIndicators.qml (+1/-1) CameraApp/advancedcamerasettings.cpp (+125/-0) CameraApp/advancedcamerasettings.h (+11/-0) ViewFinderOverlay.qml (+137/-2) ViewFinderView.qml (+15/-16) |
||||
To merge this branch: | bzr merge lp:~fboucault/camera-app/resolution_options | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Pending | |
Bill Filler | Pending | ||
Review via email: mp+278621@code.launchpad.net |
This proposal supersedes a proposal from 2015-10-14.
Commit message
New option for the user to choose between the maximum resolution the sensor allows or the resolution that fits the screen.
Description of the change
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:586
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:587
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:588
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:589
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:592
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Bill Filler (bfiller) wrote : Posted in a previous version of this proposal | # |
Framework version needs to be 15.04.3 as the required qtubuntu-camera change is not in the current 15.04.2 version that is in ota8
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:597
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:600
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:601
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal | # |
https:/
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:602
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'BottomEdgeIndicators.qml' |
2 | --- BottomEdgeIndicators.qml 2015-10-22 12:21:14 +0000 |
3 | +++ BottomEdgeIndicators.qml 2015-11-25 17:47:21 +0000 |
4 | @@ -84,7 +84,7 @@ |
5 | id: indicatorIcon |
6 | anchors.fill: parent |
7 | color: "white" |
8 | - name: modelData && modelData.isToggle ? modelData.icon : modelData.get(model.selectedIndex).icon |
9 | + name: modelData && modelData.isToggle ? modelData.icon : (modelData.get(model.selectedIndex) ? modelData.get(model.selectedIndex).icon : "") |
10 | source: name ? "image://theme/%1".arg(name) : (modelData.iconSource || "") |
11 | visible: source != "" |
12 | } |
13 | |
14 | === modified file 'CameraApp/advancedcamerasettings.cpp' |
15 | --- CameraApp/advancedcamerasettings.cpp 2015-10-27 09:17:27 +0000 |
16 | +++ CameraApp/advancedcamerasettings.cpp 2015-11-25 17:47:21 +0000 |
17 | @@ -26,6 +26,10 @@ |
18 | #include <QtMultimedia/QVideoDeviceSelectorControl> |
19 | #include <QtMultimedia/QCameraFlashControl> |
20 | #include <QtMultimedia/QCameraExposureControl> |
21 | +#include <QGuiApplication> |
22 | +#include <QScreen> |
23 | + |
24 | +#include <cmath> |
25 | |
26 | // Definition of this enum value is duplicated in qtubuntu-camera |
27 | static const QCameraExposure::ExposureMode ExposureHdr = static_cast<QCameraExposure::ExposureMode>(QCameraExposure::ExposureModeVendor + 1); |
28 | @@ -222,6 +226,12 @@ |
29 | QObject::connect(m_cameraControl, |
30 | SIGNAL(captureModeChanged(QCamera::CaptureModes)), |
31 | this, SIGNAL(resolutionChanged())); |
32 | + QObject::connect(m_cameraControl, |
33 | + SIGNAL(captureModeChanged(QCamera::CaptureModes)), |
34 | + this, SIGNAL(maximumResolutionChanged())); |
35 | + QObject::connect(m_cameraControl, |
36 | + SIGNAL(captureModeChanged(QCamera::CaptureModes)), |
37 | + this, SIGNAL(fittingResolutionChanged())); |
38 | } |
39 | |
40 | m_cameraFlashControl = flashControlFromCamera(m_camera); |
41 | @@ -237,6 +247,8 @@ |
42 | m_videoEncoderControl = videoEncoderControlFromCamera(m_camera); |
43 | |
44 | Q_EMIT resolutionChanged(); |
45 | + Q_EMIT maximumResolutionChanged(); |
46 | + Q_EMIT fittingResolutionChanged(); |
47 | Q_EMIT hasFlashChanged(); |
48 | Q_EMIT hasHdrChanged(); |
49 | Q_EMIT hdrEnabledChanged(); |
50 | @@ -260,6 +272,8 @@ |
51 | } |
52 | Q_EMIT activeCameraIndexChanged(); |
53 | Q_EMIT resolutionChanged(); |
54 | + Q_EMIT maximumResolutionChanged(); |
55 | + Q_EMIT fittingResolutionChanged(); |
56 | Q_EMIT hasFlashChanged(); |
57 | Q_EMIT videoSupportedResolutionsChanged(); |
58 | } |
59 | @@ -277,6 +291,117 @@ |
60 | return QSize(); |
61 | } |
62 | |
63 | +QSize AdvancedCameraSettings::imageCaptureResolution() const |
64 | +{ |
65 | + if (m_imageEncoderControl != 0) { |
66 | + return m_imageEncoderControl->imageSettings().resolution(); |
67 | + } |
68 | + |
69 | + return QSize(); |
70 | +} |
71 | + |
72 | +QSize AdvancedCameraSettings::videoRecorderResolution() const |
73 | +{ |
74 | + if (m_videoEncoderControl != 0) { |
75 | + return m_videoEncoderControl->videoSettings().resolution(); |
76 | + } |
77 | + |
78 | + return QSize(); |
79 | +} |
80 | + |
81 | +QSize AdvancedCameraSettings::maximumResolution() const |
82 | +{ |
83 | + if (m_imageEncoderControl) { |
84 | + QList<QSize> sizes = m_imageEncoderControl->supportedResolutions( |
85 | + m_imageEncoderControl->imageSettings()); |
86 | + |
87 | + QSize maximumSize; |
88 | + long maximumPixels = 0; |
89 | + |
90 | + QList<QSize>::const_iterator it = sizes.begin(); |
91 | + while (it != sizes.end()) { |
92 | + const long pixels = ((long)((*it).width())) * ((long)((*it).height())); |
93 | + if (pixels > maximumPixels) { |
94 | + maximumSize = *it; |
95 | + maximumPixels = pixels; |
96 | + } |
97 | + ++it; |
98 | + } |
99 | + |
100 | + return maximumSize; |
101 | + } |
102 | + |
103 | + return QSize(); |
104 | +} |
105 | + |
106 | +float AdvancedCameraSettings::getScreenAspectRatio() const |
107 | +{ |
108 | + float screenAspectRatio; |
109 | + QScreen *screen = QGuiApplication::primaryScreen(); |
110 | + Q_ASSERT(!screen); |
111 | + const int kScreenWidth = screen->geometry().width(); |
112 | + const int kScreenHeight = screen->geometry().height(); |
113 | + Q_ASSERT(kScreenWidth > 0 && kScreenHeight > 0); |
114 | + |
115 | + screenAspectRatio = (kScreenWidth > kScreenHeight) ? |
116 | + ((float)kScreenWidth / (float)kScreenHeight) : ((float)kScreenHeight / (float)kScreenWidth); |
117 | + |
118 | + return screenAspectRatio; |
119 | +} |
120 | + |
121 | +QSize AdvancedCameraSettings::fittingResolution() const |
122 | +{ |
123 | + QList<float> prioritizedAspectRatios; |
124 | + prioritizedAspectRatios.append(getScreenAspectRatio()); |
125 | + const float backAspectRatios[4] = { 16.0f/9.0f, 3.0f/2.0f, 4.0f/3.0f, 5.0f/4.0f }; |
126 | + for (int i=0; i<4; ++i) { |
127 | + if (!prioritizedAspectRatios.contains(backAspectRatios[i])) { |
128 | + prioritizedAspectRatios.append(backAspectRatios[i]); |
129 | + } |
130 | + } |
131 | + |
132 | + if (m_imageEncoderControl) { |
133 | + QList<QSize> sizes = m_imageEncoderControl->supportedResolutions( |
134 | + m_imageEncoderControl->imageSettings()); |
135 | + |
136 | + QSize optimalSize; |
137 | + long optimalPixels = 0; |
138 | + |
139 | + if (!sizes.empty()) { |
140 | + float aspectRatio; |
141 | + |
142 | + // Loop over all reported camera resolutions until we find the highest |
143 | + // one that matches the current prioritized aspect ratio. If it doesn't |
144 | + // find one on the current aspect ration, it selects the next ratio and |
145 | + // tries again. |
146 | + QList<float>::const_iterator ratioIt = prioritizedAspectRatios.begin(); |
147 | + while (ratioIt != prioritizedAspectRatios.end()) { |
148 | + // Don't update the aspect ratio when using this function for finding |
149 | + // the optimal thumbnail size as it will affect the preview window size |
150 | + aspectRatio = (*ratioIt); |
151 | + |
152 | + QList<QSize>::const_iterator it = sizes.begin(); |
153 | + while (it != sizes.end()) { |
154 | + const float ratio = (float)(*it).width() / (float)(*it).height(); |
155 | + const long pixels = ((long)((*it).width())) * ((long)((*it).height())); |
156 | + const float EPSILON = 0.02; |
157 | + if (fabs(ratio - aspectRatio) < EPSILON && pixels > optimalPixels) { |
158 | + optimalSize = *it; |
159 | + optimalPixels = pixels; |
160 | + } |
161 | + ++it; |
162 | + } |
163 | + if (optimalPixels > 0) break; |
164 | + ++ratioIt; |
165 | + } |
166 | + } |
167 | + |
168 | + return optimalSize; |
169 | + } |
170 | + |
171 | + return QSize(); |
172 | +} |
173 | + |
174 | QStringList AdvancedCameraSettings::videoSupportedResolutions() const |
175 | { |
176 | if (m_videoEncoderControl) { |
177 | |
178 | === modified file 'CameraApp/advancedcamerasettings.h' |
179 | --- CameraApp/advancedcamerasettings.h 2014-12-08 19:12:52 +0000 |
180 | +++ CameraApp/advancedcamerasettings.h 2015-11-25 17:47:21 +0000 |
181 | @@ -40,6 +40,10 @@ |
182 | Q_PROPERTY (int activeCameraIndex READ activeCameraIndex WRITE setActiveCameraIndex |
183 | NOTIFY activeCameraIndexChanged) |
184 | Q_PROPERTY (QSize resolution READ resolution NOTIFY resolutionChanged) |
185 | + Q_PROPERTY (QSize imageCaptureResolution READ imageCaptureResolution) |
186 | + Q_PROPERTY (QSize videoRecorderResolution READ videoRecorderResolution) |
187 | + Q_PROPERTY (QSize maximumResolution READ maximumResolution NOTIFY maximumResolutionChanged) |
188 | + Q_PROPERTY (QSize fittingResolution READ fittingResolution NOTIFY fittingResolutionChanged) |
189 | Q_PROPERTY (QStringList videoSupportedResolutions READ videoSupportedResolutions NOTIFY videoSupportedResolutionsChanged) |
190 | Q_PROPERTY (bool hasFlash READ hasFlash NOTIFY hasFlashChanged) |
191 | Q_PROPERTY (bool hdrEnabled READ hdrEnabled WRITE setHdrEnabled NOTIFY hdrEnabledChanged) |
192 | @@ -53,6 +57,11 @@ |
193 | void setCamera(QObject* camera); |
194 | void setActiveCameraIndex(int index); |
195 | QSize resolution() const; |
196 | + QSize imageCaptureResolution() const; |
197 | + QSize videoRecorderResolution() const; |
198 | + QSize maximumResolution() const; |
199 | + QSize fittingResolution() const; |
200 | + float getScreenAspectRatio() const; |
201 | QStringList videoSupportedResolutions() const; |
202 | bool hasFlash() const; |
203 | bool hasHdr() const; |
204 | @@ -66,6 +75,8 @@ |
205 | void cameraChanged(); |
206 | void activeCameraIndexChanged(); |
207 | void resolutionChanged(); |
208 | + void maximumResolutionChanged(); |
209 | + void fittingResolutionChanged(); |
210 | void hasFlashChanged(); |
211 | void hasHdrChanged(); |
212 | void hdrEnabledChanged(); |
213 | |
214 | === modified file 'ViewFinderOverlay.qml' |
215 | --- ViewFinderOverlay.qml 2015-11-25 17:03:06 +0000 |
216 | +++ ViewFinderOverlay.qml 2015-11-25 17:47:21 +0000 |
217 | @@ -51,6 +51,12 @@ |
218 | property bool preferRemovableStorage: false |
219 | property string videoResolution: "1920x1080" |
220 | property bool playShutterSound: true |
221 | + // FIXME: stores the resolution selected for 2 cameras. Instead it should: |
222 | + // - support any number of cameras |
223 | + // - not rely on the camera index but on Camera.deviceId |
224 | + // Ref.: http://doc.qt.io/qt-5/qml-qtmultimedia-camera.html#deviceId-prop |
225 | + property string photoResolution0 |
226 | + property string photoResolution1 |
227 | |
228 | onFlashModeChanged: if (flashMode != Camera.FlashOff) hdrEnabled = false; |
229 | onHdrEnabledChanged: if (hdrEnabled) flashMode = Camera.FlashOff |
230 | @@ -88,12 +94,83 @@ |
231 | value: settings.videoResolution |
232 | } |
233 | |
234 | + Binding { |
235 | + target: camera.imageCapture |
236 | + property: "resolution" |
237 | + value: settings["photoResolution" + camera.advanced.activeCameraIndex] |
238 | + } |
239 | + |
240 | + Connections { |
241 | + target: camera.imageCapture |
242 | + onResolutionChanged: { |
243 | + // FIXME: this is a necessary workaround because: |
244 | + // - Neither camera.viewfinder.resolution nor camera.advanced.resolution |
245 | + // emit a changed signal when the underlying AalViewfinderSettingsControl's |
246 | + // resolution changes |
247 | + // - we know that qtubuntu-camera changes the resolution of the |
248 | + // viewfinder automatically when the capture resolution is set |
249 | + // - we need camera.viewfinder.resolution to hold the right |
250 | + // value |
251 | + camera.viewfinder.resolution = camera.advanced.resolution; |
252 | + } |
253 | + } |
254 | + |
255 | + Connections { |
256 | + target: camera.videoRecorder |
257 | + onResolutionChanged: { |
258 | + // FIXME: see workaround setting camera.viewfinder.resolution above |
259 | + camera.viewfinder.resolution = camera.advanced.resolution; |
260 | + } |
261 | + } |
262 | + |
263 | + Connections { |
264 | + target: camera |
265 | + onCaptureModeChanged: { |
266 | + // FIXME: see workaround setting camera.viewfinder.resolution above |
267 | + camera.viewfinder.resolution = camera.advanced.resolution; |
268 | + } |
269 | + } |
270 | + |
271 | function resolutionToLabel(resolution) { |
272 | // takes in a resolution string (e.g. "1920x1080") and returns a nicer |
273 | // form of it for display in the UI: "1080p" |
274 | return resolution.split("x").pop() + "p"; |
275 | } |
276 | |
277 | + function sizeToString(size) { |
278 | + return size.width + "x" + size.height; |
279 | + } |
280 | + |
281 | + function stringToSize(resolution) { |
282 | + var r = resolution.split("x"); |
283 | + return Qt.size(r[0], r[1]); |
284 | + } |
285 | + |
286 | + function sizeToAspectRatio(size) { |
287 | + var ratio = Math.max(size.width, size.height) / Math.min(size.width, size.height); |
288 | + var maxDenominator = 12; |
289 | + var epsilon; |
290 | + var numerator; |
291 | + var denominator; |
292 | + var bestDenominator; |
293 | + var bestEpsilon = 10000; |
294 | + for (denominator = 2; denominator <= maxDenominator; denominator++) { |
295 | + numerator = ratio * denominator; |
296 | + epsilon = Math.abs(Math.round(numerator) - numerator); |
297 | + if (epsilon < bestEpsilon) { |
298 | + bestEpsilon = epsilon; |
299 | + bestDenominator = denominator; |
300 | + } |
301 | + } |
302 | + numerator = Math.round(ratio * bestDenominator); |
303 | + return "%1:%2".arg(numerator).arg(bestDenominator); |
304 | + } |
305 | + |
306 | + function sizeToMegapixels(size) { |
307 | + var megapixels = (size.width * size.height) / 1000000; |
308 | + return parseFloat(megapixels.toFixed(1)) |
309 | + } |
310 | + |
311 | function updateVideoResolutionOptions() { |
312 | // Clear and refill videoResolutionOptionsModel with available resolutions |
313 | // Try to only display well known resolutions: 1080p, 720p and 480p |
314 | @@ -111,25 +188,71 @@ |
315 | } |
316 | |
317 | // If resolution setting chosen is not supported select the highest available resolution |
318 | - if (supported.indexOf(settings.videoResolution) == -1) { |
319 | + if (supported.length > 0 && supported.indexOf(settings.videoResolution) == -1) { |
320 | settings.videoResolution = supported[supported.length - 1]; |
321 | } |
322 | } |
323 | |
324 | + function updatePhotoResolutionOptions() { |
325 | + // Clear and refill photoResolutionOptionsModel with available resolutions |
326 | + photoResolutionOptionsModel.clear(); |
327 | + |
328 | + var optionMaximum = {"icon": "", |
329 | + "label": "%1 (%2MP)".arg(sizeToAspectRatio(camera.advanced.maximumResolution)) |
330 | + .arg(sizeToMegapixels(camera.advanced.maximumResolution)), |
331 | + "value": sizeToString(camera.advanced.maximumResolution)}; |
332 | + |
333 | + var optionFitting = {"icon": "", |
334 | + "label": "%1 (%2MP)".arg(sizeToAspectRatio(camera.advanced.fittingResolution)) |
335 | + .arg(sizeToMegapixels(camera.advanced.fittingResolution)), |
336 | + "value": sizeToString(camera.advanced.fittingResolution)}; |
337 | + |
338 | + photoResolutionOptionsModel.insert(0, optionMaximum); |
339 | + if (camera.advanced.fittingResolution != camera.advanced.maximumResolution) { |
340 | + photoResolutionOptionsModel.insert(1, optionFitting); |
341 | + } |
342 | + |
343 | + var photoResolution = settings["photoResolution" + camera.advanced.activeCameraIndex]; |
344 | + // If resolution setting chosen is not supported select the fitting resolution |
345 | + if (photoResolution != optionFitting.value && |
346 | + photoResolution != optionMaximum.value) { |
347 | + settings["photoResolution" + camera.advanced.activeCameraIndex] = optionFitting.value; |
348 | + } |
349 | + } |
350 | + |
351 | Component.onCompleted: { |
352 | + camera.cameraState = Camera.LoadedState; |
353 | updateVideoResolutionOptions(); |
354 | + updatePhotoResolutionOptions(); |
355 | + // FIXME: see workaround setting camera.viewfinder.resolution above |
356 | + camera.viewfinder.resolution = camera.advanced.resolution; |
357 | + camera.cameraState = Camera.ActiveState; |
358 | } |
359 | |
360 | Connections { |
361 | target: camera.advanced |
362 | onVideoSupportedResolutionsChanged: updateVideoResolutionOptions(); |
363 | + onFittingResolutionChanged: updatePhotoResolutionOptions(); |
364 | + onMaximumResolutionChanged: updatePhotoResolutionOptions(); |
365 | } |
366 | |
367 | Connections { |
368 | target: camera.advanced |
369 | onActiveCameraIndexChanged: { |
370 | + var hasPhotoResolutionSetting = (settings["photoResolution" + camera.advanced.activeCameraIndex] != "") |
371 | + // FIXME: use camera.advanced.imageCaptureResolution instead of camera.imageCapture.resolution |
372 | + // because the latter is not updated when the backend changes the resolution |
373 | + settings["photoResolution" + camera.advanced.activeCameraIndex] = sizeToString(camera.advanced.imageCaptureResolution); |
374 | + settings.videoResolution = sizeToString(camera.advanced.videoRecorderResolution); |
375 | + updatePhotoResolutionOptions(); |
376 | updateVideoResolutionOptions(); |
377 | - camera.videoRecorder.resolution = settings.videoResolution; |
378 | + // FIXME: see workaround setting camera.viewfinder.resolution above |
379 | + camera.viewfinder.resolution = camera.advanced.resolution; |
380 | + |
381 | + // If no resolution has ever been chosen, select the one that fits the screen |
382 | + if (!hasPhotoResolutionSetting) { |
383 | + settings["photoResolution" + camera.advanced.activeCameraIndex] = sizeToString(camera.advanced.fittingResolution); |
384 | + } |
385 | } |
386 | } |
387 | |
388 | @@ -428,6 +551,18 @@ |
389 | label: QT_TR_NOOP("Off") |
390 | value: false |
391 | } |
392 | + }, |
393 | + ListModel { |
394 | + id: photoResolutionOptionsModel |
395 | + |
396 | + property string settingsProperty: "photoResolution" + camera.advanced.activeCameraIndex |
397 | + property string icon: "" |
398 | + property string label: sizeToAspectRatio(stringToSize(settings[settingsProperty])) |
399 | + property bool isToggle: false |
400 | + property int selectedIndex: bottomEdge.indexForValue(photoResolutionOptionsModel, settings[settingsProperty]) |
401 | + property bool available: true |
402 | + property bool visible: camera.captureMode == Camera.CaptureStillImage |
403 | + property bool showInIndicators: false |
404 | } |
405 | ] |
406 | |
407 | |
408 | === modified file 'ViewFinderView.qml' |
409 | --- ViewFinderView.qml 2015-11-16 15:54:25 +0000 |
410 | +++ ViewFinderView.qml 2015-11-25 17:47:21 +0000 |
411 | @@ -36,6 +36,7 @@ |
412 | Camera { |
413 | id: camera |
414 | captureMode: Camera.CaptureStillImage |
415 | + cameraState: Camera.UnloadedState |
416 | StateSaver.properties: "captureMode" |
417 | |
418 | function manualFocus(x, y) { |
419 | @@ -67,10 +68,6 @@ |
420 | StateSaver.properties: "activeCameraIndex" |
421 | } |
422 | |
423 | - Component.onCompleted: { |
424 | - camera.start(); |
425 | - } |
426 | - |
427 | /* Use only digital zoom for now as it's what phone cameras mostly use. |
428 | TODO: if optical zoom is available, maximumZoom should be the combined |
429 | range of optical and digital zoom and currentZoom should adjust the two |
430 | @@ -121,12 +118,14 @@ |
431 | target: Qt.application |
432 | onActiveChanged: { |
433 | if (Qt.application.active) { |
434 | - camera.start() |
435 | + if (camera.cameraState == Camera.LoadedState) { |
436 | + camera.cameraState = Camera.ActiveState; |
437 | + } |
438 | } else if (!application.desktopMode) { |
439 | if (camera.videoRecorder.recorderState == CameraRecorder.RecordingState) { |
440 | camera.videoRecorder.stop(); |
441 | } |
442 | - camera.stop() |
443 | + camera.cameraState = Camera.LoadedState; |
444 | } |
445 | } |
446 | } |
447 | @@ -250,16 +249,16 @@ |
448 | axis.x: 0; axis.y: 1; axis.z: 0 |
449 | angle: application.desktopMode ? 180 : 0 |
450 | } |
451 | - |
452 | - ViewFinderGeometry { |
453 | - id: viewFinderGeometry |
454 | - anchors.centerIn: parent |
455 | - |
456 | - cameraResolution: camera.advanced.resolution |
457 | - viewFinderHeight: viewFinder.height |
458 | - viewFinderWidth: viewFinder.width |
459 | - viewFinderOrientation: viewFinder.orientation |
460 | - } |
461 | + } |
462 | + |
463 | + ViewFinderGeometry { |
464 | + id: viewFinderGeometry |
465 | + anchors.centerIn: parent |
466 | + |
467 | + cameraResolution: camera.viewfinder.resolution |
468 | + viewFinderHeight: viewFinder.height |
469 | + viewFinderWidth: viewFinder.width |
470 | + viewFinderOrientation: viewFinder.orientation |
471 | } |
472 | |
473 | Item { |
Depends on https:/ /code.launchpad .net/~fboucault /qtubuntu- camera/ resolution_ fixes/+ merge/274404