Changeset View
Changeset View
Standalone View
Standalone View
kcm/src/declarative/qmlscreen.cpp
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Line(s) | |||||
44 | { | 44 | { | ||
45 | return m_config; | 45 | return m_config; | ||
46 | } | 46 | } | ||
47 | 47 | | |||
48 | void QMLScreen::setConfig(const KScreen::ConfigPtr &config) | 48 | void QMLScreen::setConfig(const KScreen::ConfigPtr &config) | ||
49 | { | 49 | { | ||
50 | qDeleteAll(m_outputMap); | 50 | qDeleteAll(m_outputMap); | ||
51 | m_outputMap.clear(); | 51 | m_outputMap.clear(); | ||
52 | m_manuallyMovedOutputs.clear(); | ||||
52 | m_bottommost = m_leftmost = m_rightmost = m_topmost = nullptr; | 53 | m_bottommost = m_leftmost = m_rightmost = m_topmost = nullptr; | ||
53 | m_connectedOutputsCount = 0; | 54 | m_connectedOutputsCount = 0; | ||
54 | m_enabledOutputsCount = 0; | 55 | m_enabledOutputsCount = 0; | ||
55 | 56 | | |||
56 | if (m_config) { | 57 | if (m_config) { | ||
57 | m_config->disconnect(this); | 58 | m_config->disconnect(this); | ||
58 | } | 59 | } | ||
59 | 60 | | |||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Line(s) | |||||
170 | 171 | | |||
171 | QSize QMLScreen::maxScreenSize() const | 172 | QSize QMLScreen::maxScreenSize() const | ||
172 | { | 173 | { | ||
173 | return m_config->screen()->maxSize(); | 174 | return m_config->screen()->maxSize(); | ||
174 | } | 175 | } | ||
175 | 176 | | |||
176 | float QMLScreen::outputScale() const | 177 | float QMLScreen::outputScale() const | ||
177 | { | 178 | { | ||
178 | return 1.0 / 12.0; | 179 | return m_outputScale; | ||
179 | } | 180 | } | ||
180 | 181 | | |||
181 | void QMLScreen::outputConnectedChanged() | 182 | void QMLScreen::outputConnectedChanged() | ||
182 | { | 183 | { | ||
183 | int connectedCount = 0; | 184 | int connectedCount = 0; | ||
184 | 185 | | |||
185 | Q_FOREACH (const KScreen::OutputPtr &output, m_outputMap.keys()) { | 186 | Q_FOREACH (const KScreen::OutputPtr &output, m_outputMap.keys()) { | ||
186 | if (output->isConnected()) { | 187 | if (output->isConnected()) { | ||
Show All 33 Lines | 220 | { | |||
220 | /* TODO: Reposition the QMLOutputs */ | 221 | /* TODO: Reposition the QMLOutputs */ | ||
221 | } | 222 | } | ||
222 | 223 | | |||
223 | void QMLScreen::qmlOutputMoved(QMLOutput *qmlOutput) | 224 | void QMLScreen::qmlOutputMoved(QMLOutput *qmlOutput) | ||
224 | { | 225 | { | ||
225 | if (qmlOutput->isCloneMode()) { | 226 | if (qmlOutput->isCloneMode()) { | ||
226 | return; | 227 | return; | ||
227 | } | 228 | } | ||
229 | if (!m_manuallyMovedOutputs.contains(qmlOutput)) | ||||
230 | m_manuallyMovedOutputs.append(qmlOutput); | ||||
228 | 231 | | |||
229 | updateCornerOutputs(); | 232 | updateCornerOutputs(); | ||
230 | 233 | | |||
231 | if (m_leftmost) { | 234 | if (m_leftmost) { | ||
232 | m_leftmost->setOutputX(0); | 235 | m_leftmost->setOutputX(0); | ||
233 | } | 236 | } | ||
234 | if (m_topmost) { | 237 | if (m_topmost) { | ||
235 | m_topmost->setOutputY(0); | 238 | m_topmost->setOutputY(0); | ||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Line(s) | 286 | Q_FOREACH (QMLOutput *output, m_outputMap) { | |||
299 | } | 302 | } | ||
300 | 303 | | |||
301 | if (!other || output->y() + output->height() > other->y() + other->height()) { | 304 | if (!other || output->y() + output->height() > other->y() + other->height()) { | ||
302 | m_bottommost = output; | 305 | m_bottommost = output; | ||
303 | } | 306 | } | ||
304 | } | 307 | } | ||
305 | } | 308 | } | ||
306 | 309 | | |||
310 | void QMLScreen::setOutputScale(float scale) | ||||
311 | { | ||||
312 | if (qFuzzyCompare(scale, m_outputScale)) | ||||
313 | return; | ||||
314 | m_outputScale = scale; | ||||
315 | emit outputScaleChanged(); | ||||
316 | } | ||||
317 | | ||||
307 | void QMLScreen::updateOutputsPlacement() | 318 | void QMLScreen::updateOutputsPlacement() | ||
308 | { | 319 | { | ||
309 | QSizeF activeScreenSize; | 320 | if (width() <= 0) | ||
321 | return; | ||||
322 | | ||||
323 | QSizeF initialActiveScreenSize; | ||||
310 | 324 | | |||
311 | Q_FOREACH (QQuickItem *item, childItems()) { | 325 | Q_FOREACH (QQuickItem *item, childItems()) { | ||
312 | QMLOutput *qmlOutput = qobject_cast<QMLOutput*>(item); | 326 | QMLOutput *qmlOutput = qobject_cast<QMLOutput*>(item); | ||
313 | if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled()) { | 327 | if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled()) { | ||
314 | continue; | 328 | continue; | ||
315 | } | 329 | } | ||
316 | 330 | | |||
317 | if (qmlOutput->outputX() + qmlOutput->currentOutputWidth() > activeScreenSize.width()) { | 331 | if (qmlOutput->outputX() + qmlOutput->currentOutputWidth() > initialActiveScreenSize.width()) { | ||
318 | activeScreenSize.setWidth(qmlOutput->outputX() + qmlOutput->currentOutputWidth()); | 332 | initialActiveScreenSize.setWidth(qmlOutput->outputX() + qmlOutput->currentOutputWidth()); | ||
319 | } | 333 | } | ||
320 | if (qmlOutput->outputY() + qmlOutput->currentOutputHeight() > activeScreenSize.height()) { | 334 | if (qmlOutput->outputY() + qmlOutput->currentOutputHeight() > initialActiveScreenSize.height()) { | ||
321 | activeScreenSize.setHeight(qmlOutput->outputY() + qmlOutput->currentOutputHeight()); | 335 | initialActiveScreenSize.setHeight(qmlOutput->outputY() + qmlOutput->currentOutputHeight()); | ||
322 | } | 336 | } | ||
323 | } | 337 | } | ||
324 | 338 | | |||
325 | activeScreenSize *= outputScale(); | 339 | auto initialScale = outputScale(); | ||
340 | auto scale = initialScale; | ||||
341 | qreal lastX = -1.0; | ||||
342 | do { | ||||
343 | auto activeScreenSize = initialActiveScreenSize * scale; | ||||
326 | 344 | | |||
327 | const QPointF offset((width() - activeScreenSize.width()) / 2.0, | 345 | const QPointF offset((width() - activeScreenSize.width()) / 2.0, | ||
328 | (height() - activeScreenSize.height()) / 2.0); | 346 | (height() - activeScreenSize.height()) / 2.0); | ||
329 | 347 | | |||
330 | qreal lastX = -1.0; | 348 | lastX = -1.0; | ||
331 | qreal lastY = -1.0; | 349 | qreal lastY = -1.0; | ||
332 | Q_FOREACH (QQuickItem *item, childItems()) { | 350 | Q_FOREACH (QQuickItem *item, childItems()) { | ||
333 | QMLOutput *qmlOutput = qobject_cast<QMLOutput*>(item); | 351 | QMLOutput *qmlOutput = qobject_cast<QMLOutput*>(item); | ||
334 | if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled()) { | 352 | if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled() || | ||
353 | m_manuallyMovedOutputs.contains(qmlOutput)) { | ||||
335 | continue; | 354 | continue; | ||
336 | } | 355 | } | ||
337 | 356 | | |||
338 | qmlOutput->blockSignals(true); | 357 | qmlOutput->blockSignals(true); | ||
339 | qmlOutput->setPosition(QPointF(offset.x() + (qmlOutput->outputX() * outputScale()), | 358 | qmlOutput->setPosition(QPointF(offset.x() + (qmlOutput->outputX() * scale), | ||
340 | offset.y() + (qmlOutput->outputY() * outputScale()))); | 359 | offset.y() + (qmlOutput->outputY() * scale))); | ||
341 | lastX = qMax(lastX, qmlOutput->position().x() + qmlOutput->size().width()); | 360 | lastX = qMax(lastX, qmlOutput->position().x() + qmlOutput->size().width() / initialScale * scale); | ||
342 | lastY = qMax(lastY, qmlOutput->position().y()); | 361 | lastY = qMax(lastY, qmlOutput->position().y()); | ||
343 | qmlOutput->blockSignals(false); | 362 | qmlOutput->blockSignals(false); | ||
344 | } | 363 | } | ||
345 | 364 | | |||
346 | Q_FOREACH (QQuickItem *item, childItems()) { | 365 | Q_FOREACH (QQuickItem *item, childItems()) { | ||
347 | QMLOutput *qmlOutput = qobject_cast<QMLOutput*>(item); | 366 | QMLOutput *qmlOutput = qobject_cast<QMLOutput*>(item); | ||
348 | if (qmlOutput->output()->isConnected() && !qmlOutput->output()->isEnabled()) { | 367 | if (qmlOutput->output()->isConnected() && !qmlOutput->output()->isEnabled() && | ||
368 | !m_manuallyMovedOutputs.contains(qmlOutput)) { | ||||
349 | qmlOutput->blockSignals(true); | 369 | qmlOutput->blockSignals(true); | ||
350 | qmlOutput->setPosition(QPointF(lastX, lastY)); | 370 | qmlOutput->setPosition(QPointF(lastX, lastY)); | ||
351 | lastX += qmlOutput->size().width(); | 371 | lastX += qmlOutput->size().width() / initialScale * scale; | ||
352 | qmlOutput->blockSignals(false); | 372 | qmlOutput->blockSignals(false); | ||
353 | } | 373 | } | ||
354 | } | 374 | } | ||
375 | // calculate the scale dynamically, so all screens fit to the dialog | ||||
376 | if (lastX > width()) { | ||||
377 | scale *= 0.8; | ||||
378 | } | ||||
379 | } while (lastX > width()); | ||||
380 | // Use a timer to avoid binding loop on width() | ||||
381 | QTimer::singleShot(0, this, [scale, this] { | ||||
382 | setOutputScale(scale); | ||||
383 | }); | ||||
355 | } | 384 | } |