[KPhotoAlbum] [PATCH 2/3] SettingsData: Default window geometry calculated

Michael Witten mfwitten at MIT.EDU
Tue Sep 23 04:18:10 BST 2008


There should almost never be a problem now with window geometry;
take a look at the code for a detail description (in comments)
of what is going on; I admittedly went a little overboard, but
it was fun and it works and it should be pretty efficient.

One problem that I forsee is that the code forces the window to
be completely within the primary screen.

Perhaps I will remedy this situation in another patch.

Another possible problem is that the geometry (without the frame)
is saved and restored. I have some code in place to account for
this, but it's a hardcoded hack.

Qt 4.2 actually provides a mechanism for saving and restoring
window state:

    (1) QWidget::saveGeometry()
    (2) QWidget::restoreGeometry()

Maybe that's better to use, as it handles screens already and
other state bits, such as whether the window is maximized.
However, it doesn't provide centering and the implementation
looks kind of messy.

Signed-off-by: Michael Witten <mfwitten at mit.edu>
---
 Settings/SettingsData.cpp |   96 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 95 insertions(+), 1 deletions(-)

diff --git a/Settings/SettingsData.cpp b/Settings/SettingsData.cpp
index 2aa9fe2..4a9ef80 100644
--- a/Settings/SettingsData.cpp
+++ b/Settings/SettingsData.cpp
@@ -479,5 +479,99 @@ void SettingsData::setWindowGeometry( WindowType win, const QRect& geometry )
 
 QRect SettingsData::windowGeometry( WindowType win ) const
 {
-    return value( "Window Geometry", win, QRect(0,0,800,600) );
+    QRect r( 0,0,0,0 );
+    r = value( "Window Geometry", win, r );
+
+    // If the setting does not exist or if the stored rectangle
+    // is not within the available screen, assume there is a
+    // problem and recalculate a new default geometry for the
+    // window:
+
+        QDesktopWidget* d = QApplication::desktop();
+        QRect available = d->availableGeometry( d->primaryScreen() );
+
+        if ( r.width() && available.contains(r,true) )
+            return r;
+
+    // It must be necessary to calculate a default window size. Because
+    // every cycle is more coal burned at the power plant, we have a
+    // moral obligation to optimize this calculation. The following will
+    // develop some ideas in terms of constants that compilers should
+    // use during compilation time.
+    //
+    // A typical display might have the following dimensions:
+
+            const float screenW = 1440;
+            const float screenH =  900;
+
+    // However, let's assume that the border around the screen has been
+    // commandeered and is not available:
+
+            const float availableW = screenW - 100;
+            const float availableH = screenH - 200;
+
+    // Also, because Qt is cross-platform, it is unknown how the frame
+    // (window decorations) affect the window geometry.
+    //
+    // Let's assume that most frames look roughly the same:
+    //
+    //      (1) A title bar of appreciable size, say:
+
+                    const float titleSize = 20;
+
+    //      (2) Three other borders of less appreciable size:
+
+                    const float borderSize = 5;
+
+    // Eventually, it will be necessary to readjust the location of the
+    // window, assuming titleSize >= borderSize:
+
+            const float adjustForTitle = (titleSize - borderSize) / 2;
+
+    // Now, a good default window size (without a frame) on a screen with
+    // this usable space has the following:
+
+            const float defaultW = 800 - borderSize * 2;
+            const float defaultH = 600 - titleSize - borderSize;
+
+    // Then, we must have the following ratios:
+
+            const float ratioW = defaultW/availableW;
+            const float ratioH = defaultH/availableH;
+
+    // In this case, the actually available space is given as:
+
+            float actuallyAvailableW = available.width();
+            float actuallyAvailableH = available.height();
+
+    // Thus, the dimensions of the window should be:
+
+        float w = ratioW * actuallyAvailableW;
+        float h = ratioH * actuallyAvailableH;
+
+    // To center the window, we pretend the window is in the top left corner
+    // of the the available space and then move the window halfway to the
+    // right side of the screen and halfway to the bottom of the screen:
+    //
+    //      distToMoveRight = (actuallyAvailableW - w) / 2 = (1-ratioW)*actuallyAvailableW/2
+    //      distToMoveDown  = (actuallyAvailableH - h) / 2 = (1-ratioH)*actuallyAvailableH/2
+    //
+    // Let's name those factors:
+
+        const float centeringFactorW = (1-ratioW)/2;
+        const float centeringFactorH = (1-ratioH)/2;
+
+    // So, within the available space:
+
+        float distToMoveRight = centeringFactorW * actuallyAvailableW;                   // (availableW - w) / 2 = (1-ratioW)*availableW/2
+        float distToMoveDown  = centeringFactorH * actuallyAvailableH + adjustForTitle;  // (availableH - h) / 2 = (1-ratioH)*availableH/2
+
+    // Within the screen space:
+
+        r = QRect( available.left() + distToMoveRight, available.top() + distToMoveDown, w, h );
+
+    // Set it and forget it! It's just that easy!
+
+        setValue( "Window Geometry", win, r );
+        return r;
 }
-- 
1.6.0.2.302.ge6cbd1




More information about the Kphotoalbum mailing list