]> git.sesse.net Git - vlc/commitdiff
* skins2/src/theme.cpp: Improved the saving/loading of skins config
authorOlivier Teulière <ipkiss@videolan.org>
Fri, 18 Aug 2006 18:58:16 +0000 (18:58 +0000)
committerOlivier Teulière <ipkiss@videolan.org>
Fri, 18 Aug 2006 18:58:16 +0000 (18:58 +0000)
   - the format of the skins2-config variable has changed (not backwards-compatible)
   - the active layout and its size are now restored
   - the windows and layouts are now identified by their id, instead of their
     order in the XML file; this fixes problems of disappearing windows
     when editing a skin (commenting a Window for example)
   - it should now be impossible to have all windows hidden at the same time
     (but there is no check that the windows are on screen)

modules/gui/skins2/src/theme.cpp

index 07c8f75f080ad00b5dfc6a40ee352496c8ec0f8a..696e9c3f2cef8b70f1f6d84a5dbe8278f219967c 100644 (file)
@@ -23,6 +23,8 @@
  *****************************************************************************/
 
 #include "theme.hpp"
+#include "top_window.hpp"
+#include <sstream>
 
 
 Theme::~Theme()
@@ -50,39 +52,77 @@ void Theme::loadConfig()
     // Is there an existing config?
     if( !strcmp( save, "" ) )
     {
-        // Show the windows
+        // Show the windows as indicated by the XML file
         m_windowManager.showAll( true );
         return;
     }
 
-    // Initialization
-    map<string, TopWindowPtr>::const_iterator it;
-    int i = 0;
-    int x, y, visible, scan;
+    istringstream inStream(save);
+    free( save );
 
-    // Get config for each window
-    for( it = m_windows.begin(); it != m_windows.end(); it++ )
+    char sep;
+    string winId, layId;
+    int x, y, width, height, visible;
+    bool somethingVisible = false;
+    while( !inStream.eof() )
     {
-        TopWindow *pWin = (*it).second.get();
-        // Get config
-        scan = sscanf( &save[i * 13], "(%4d,%4d,%1d)", &x, &y, &visible );
+        inStream >> sep;
+        if( sep != '[' ) goto invalid;
+        inStream >> winId >> layId >> x >> y >> width >> height >> visible >> sep >> ws;
+        if( sep != ']' ) goto invalid;
+
+        // Try to find the window and the layout
+        map<string, TopWindowPtr>::const_iterator itWin;
+        map<string, GenericLayoutPtr>::const_iterator itLay;
+        itWin = m_windows.find( winId );
+        itLay = m_layouts.find( layId );
+        if( itWin == m_windows.end() || itLay == m_layouts.end() )
+        {
+            goto invalid;
+        }
+        TopWindow *pWin = itWin->second.get();
+        GenericLayout *pLayout = itLay->second.get();
 
-        // If config has the correct number of arguments
-        if( scan > 2 )
+        // Restore the layout
+        m_windowManager.setActiveLayout( *pWin, *pLayout );
+        if( pLayout->getWidth() != width ||
+            pLayout->getHeight() != height )
         {
+            // XXX FIXME XXX: big kludge
+            // As resizing a hidden window causes some trouble (at least on
+            // Windows), first show the window off screen, resize it, and
+            // hide it again.
+            // This has to be investigated more deeply!
             m_windowManager.startMove( *pWin );
-            m_windowManager.move( *pWin, x, y );
+            m_windowManager.move( *pWin, -width - pLayout->getWidth(), 0);
             m_windowManager.stopMove();
-            if( visible )
-            {
-                m_windowManager.show( *pWin );
-            }
+            m_windowManager.show( *pWin );
+            m_windowManager.startResize( *pLayout, WindowManager::kResizeSE );
+            m_windowManager.resize( *pLayout, width, height );
+            m_windowManager.stopResize();
+            m_windowManager.hide( *pWin );
         }
+        // Move the window (which incidentally takes care of the anchoring)
+        m_windowManager.startMove( *pWin );
+        m_windowManager.move( *pWin, x, y );
+        m_windowManager.stopMove();
+        if( visible )
+        {
+            somethingVisible = true;
+            m_windowManager.show( *pWin );
+        }
+    }
 
-        // Next window
-        i++;
+    if( !somethingVisible )
+    {
+        goto invalid;
     }
-    free( save );
+    return;
+
+invalid:
+    msg_Warn( getIntf(), "invalid config: %s", inStream.str().c_str() );
+    // Restore the visibility defined in the theme
+    m_windowManager.showAll( true );
 }
 
 
@@ -90,29 +130,32 @@ void Theme::saveConfig()
 {
     msg_Dbg( getIntf(), "saving theme configuration");
 
-    // Initialize char where config is stored
-    char *save  = new char[400];
-    map<string, TopWindowPtr>::const_iterator it;
-    int i = 0;
-    int x, y;
-
-    // Save config of every window
-    for( it = m_windows.begin(); it != m_windows.end(); it++ )
+    map<string, TopWindowPtr>::const_iterator itWin;
+    map<string, GenericLayoutPtr>::const_iterator itLay;
+    ostringstream outStream;
+    for( itWin = m_windows.begin(); itWin != m_windows.end(); itWin++ )
     {
-        TopWindow *pWin = (*it).second.get();
-        // Print config
-        x = pWin->getLeft();
-        y = pWin->getTop();
-        sprintf( &save[i * 13], "(%4d,%4d,%1d)", x, y,
-            pWin->getVisibleVar().get() );
-        i++;
+        TopWindow *pWin = itWin->second.get();
+
+        // Find the layout id for this window
+        string layoutId;
+        const GenericLayout *pLayout = &pWin->getActiveLayout();
+        for( itLay = m_layouts.begin(); itLay != m_layouts.end(); itLay++ )
+        {
+            if( itLay->second.get() == pLayout )
+            {
+                layoutId = itLay->first;
+            }
+        }
+
+        outStream << '[' << itWin->first << ' ' << layoutId << ' '
+            << pWin->getLeft() << ' ' << pWin->getTop() << ' '
+            << pLayout->getWidth() << ' ' << pLayout->getHeight() << ' '
+            << (pWin->getVisibleVar().get() ? 1 : 0) << ']';
     }
 
     // Save config to file
-    config_PutPsz( getIntf(), "skins2-config", save );
-
-    // Free memory
-    delete[] save;
+    config_PutPsz( getIntf(), "skins2-config", outStream.str().c_str() );
 }