]> git.cworth.org Git - vogl/commitdiff
UI: Add a settings file
authorPeterLValve <peterl@valvesoftware.com>
Mon, 24 Mar 2014 22:55:07 +0000 (15:55 -0700)
committerCarl Worth <cworth@cworth.org>
Tue, 1 Apr 2014 19:37:32 +0000 (12:37 -0700)
* When vogleditor is started, the settings file will be loaded / saved so that it contains all the latest settings.
* The JSON settings file is stored in $XDG_CONFIG_HOME/vogleditor/ or $HOME/.config/vogleditor/ and is named vogleditor_settings.json.
* Before manually editing the file, vogleditor should be closed; after editing the file, reopen vogleditor to read in the latest changes.
* The file is automatically saved when vogleditor is closed, so manual edits while the file is open will cause the changes to be overwritten.
* Current settings include:
  * Window position and dimensions (defaults to 0,0 and 1024x768)
  * The "trim_large_trace_prompt_size" (defaults to 200) which is the minimum number of frames a trace file must contain in order for the trim trace prompt to be displayed when loading a trace file.

src/vogleditor/CMakeLists.txt
src/vogleditor/vogleditor.cpp
src/vogleditor/vogleditor_settings.cpp [new file with mode: 0644]
src/vogleditor/vogleditor_settings.h [new file with mode: 0644]

index 3132f70802318a7fc06560f2ee22163a1d8cf82f..03d91a19fbf4d2b64a1e14be3ac2860e1a937c48 100644 (file)
@@ -54,6 +54,7 @@ set(SRC_LIST
     vogleditor_qtextureviewer.cpp
     vogleditor_qtimelineview.cpp
     vogleditor_qtrimdialog.cpp
+    vogleditor_settings.cpp
     vogleditor_statetreearbprogramitem.cpp
     vogleditor_statetreearbprogramenvitem.cpp
     vogleditor_statetreebufferitem.cpp
@@ -103,6 +104,7 @@ set(HEADER_LIST
     vogleditor_apicalltreeitem.h
     vogleditor_frameitem.h
     vogleditor_gl_state_snapshot.h
+    vogleditor_settings.h
     vogleditor_snapshotitem.h
     vogleditor_statetreearbprogramitem.h
     vogleditor_statetreearbprogramenvitem.h
index 1b976ca4f4edfba51f030b31d316bac73b3fde7e..7eb513ef503e4220a3c4c65bbbe4d5c2891ff24c 100644 (file)
@@ -48,6 +48,7 @@
 #include "vogl_trace_file_reader.h"
 #include "vogl_trace_file_writer.h"
 #include "vogleditor_qstatetreemodel.h"
+#include "vogleditor_settings.h"
 #include "vogleditor_statetreetextureitem.h"
 #include "vogleditor_statetreeprogramitem.h"
 #include "vogleditor_statetreeshaderitem.h"
@@ -63,6 +64,8 @@
 //----------------------------------------------------------------------------------------------------------------------
 static void *g_actual_libgl_module_handle;
 static QString g_PROJECT_NAME = "Vogl Editor";
+static vogleditor_settings g_settings;
+static const char* g_SETTINGS_FILE = "./vogleditor_settings.json";
 
 //----------------------------------------------------------------------------------------------------------------------
 // vogl_get_proc_address_helper
@@ -136,6 +139,15 @@ VoglEditor::VoglEditor(QWidget *parent) :
       vogl_init_actual_gl_entrypoints(vogl_get_proc_address_helper);
    }
 
+   // load the settings file. This will only succeed if the file already exists
+   g_settings.load(g_SETTINGS_FILE);
+
+   // always save/resave the file wiill either be created or so that new settings will be added
+   g_settings.save(g_SETTINGS_FILE);
+
+   this->move(g_settings.window_position_left(), g_settings.window_position_top());
+   this->resize(g_settings.window_size_width(), g_settings.window_size_height());
+
    m_pStatusLabel = new QLabel(ui->statusBar);
    m_pStatusLabel->setBaseSize(150, 12);
    ui->statusBar->addWidget(m_pStatusLabel, 1);
@@ -201,98 +213,105 @@ VoglEditor::VoglEditor(QWidget *parent) :
 
 VoglEditor::~VoglEditor()
 {
-   close_trace_file();
-   delete ui;
+    // update any settings and save the settings file
+    g_settings.set_window_position_left(this->x());
+    g_settings.set_window_position_top(this->y());
+    g_settings.set_window_size_width(this->width());
+    g_settings.set_window_size_height(this->height());
+    g_settings.save(g_SETTINGS_FILE);
 
-   if (m_pStatusLabel != NULL)
-   {
-       delete m_pStatusLabel;
-       m_pStatusLabel = NULL;
-   }
+    close_trace_file();
+    delete ui;
 
-   if (m_pFramebufferExplorer != NULL)
-   {
-       delete m_pFramebufferExplorer;
-       m_pFramebufferExplorer = NULL;
-   }
+    if (m_pStatusLabel != NULL)
+    {
+        delete m_pStatusLabel;
+        m_pStatusLabel = NULL;
+    }
 
-   if (m_pTextureExplorer != NULL)
-   {
-       delete m_pTextureExplorer;
-       m_pTextureExplorer = NULL;
-   }
+    if (m_pFramebufferExplorer != NULL)
+    {
+        delete m_pFramebufferExplorer;
+        m_pFramebufferExplorer = NULL;
+    }
 
-   if (m_pRenderbufferExplorer != NULL)
-   {
-       delete m_pRenderbufferExplorer;
-       m_pRenderbufferExplorer = NULL;
-   }
+    if (m_pTextureExplorer != NULL)
+    {
+        delete m_pTextureExplorer;
+        m_pTextureExplorer = NULL;
+    }
 
-   if (m_pProgramExplorer != NULL)
-   {
-       delete m_pProgramExplorer;
-       m_pProgramExplorer = NULL;
-   }
+    if (m_pRenderbufferExplorer != NULL)
+    {
+        delete m_pRenderbufferExplorer;
+        m_pRenderbufferExplorer = NULL;
+    }
 
-   if (m_pShaderExplorer != NULL)
-   {
-       delete m_pShaderExplorer;
-       m_pShaderExplorer = NULL;
-   }
+    if (m_pProgramExplorer != NULL)
+    {
+        delete m_pProgramExplorer;
+        m_pProgramExplorer = NULL;
+    }
 
-   if (m_pPlayButton != NULL)
-   {
-       delete m_pPlayButton;
-       m_pPlayButton = NULL;
-   }
+    if (m_pShaderExplorer != NULL)
+    {
+        delete m_pShaderExplorer;
+        m_pShaderExplorer = NULL;
+    }
 
-   if (m_pTrimButton != NULL)
-   {
-       delete m_pTrimButton;
-       m_pTrimButton = NULL;
-   }
+    if (m_pPlayButton != NULL)
+    {
+        delete m_pPlayButton;
+        m_pPlayButton = NULL;
+    }
 
-   if (m_pFramebufferTab_layout != NULL)
-   {
-       delete m_pFramebufferTab_layout;
-       m_pFramebufferTab_layout = NULL;
-   }
+    if (m_pTrimButton != NULL)
+    {
+        delete m_pTrimButton;
+        m_pTrimButton = NULL;
+    }
 
-   if (m_pTextureTab_layout != NULL)
-   {
-       delete m_pTextureTab_layout;
-       m_pTextureTab_layout = NULL;
-   }
+    if (m_pFramebufferTab_layout != NULL)
+    {
+        delete m_pFramebufferTab_layout;
+        m_pFramebufferTab_layout = NULL;
+    }
 
-   if (m_pRenderbufferTab_layout != NULL)
-   {
-       delete m_pRenderbufferTab_layout;
-       m_pRenderbufferTab_layout = NULL;
-   }
+    if (m_pTextureTab_layout != NULL)
+    {
+        delete m_pTextureTab_layout;
+        m_pTextureTab_layout = NULL;
+    }
 
-   if (m_pProgramTab_layout != NULL)
-   {
-       delete m_pProgramTab_layout;
-       m_pProgramTab_layout = NULL;
-   }
+    if (m_pRenderbufferTab_layout != NULL)
+    {
+        delete m_pRenderbufferTab_layout;
+        m_pRenderbufferTab_layout = NULL;
+    }
 
-   if (m_pShaderTab_layout != NULL)
-   {
-       delete m_pShaderTab_layout;
-       m_pShaderTab_layout = NULL;
-   }
+    if (m_pProgramTab_layout != NULL)
+    {
+        delete m_pProgramTab_layout;
+        m_pProgramTab_layout = NULL;
+    }
 
-   if (m_pStateTreeModel != NULL)
-   {
-       delete m_pStateTreeModel;
-       m_pStateTreeModel = NULL;
-   }
+    if (m_pShaderTab_layout != NULL)
+    {
+        delete m_pShaderTab_layout;
+        m_pShaderTab_layout = NULL;
+    }
 
-   if (m_pVoglReplayProcess != NULL)
-   {
-       delete m_pVoglReplayProcess;
-       m_pVoglReplayProcess = NULL;
-   }
+    if (m_pStateTreeModel != NULL)
+    {
+        delete m_pStateTreeModel;
+        m_pStateTreeModel = NULL;
+    }
+
+    if (m_pVoglReplayProcess != NULL)
+    {
+        delete m_pVoglReplayProcess;
+        m_pVoglReplayProcess = NULL;
+    }
 }
 
 void VoglEditor::playCurrentTraceFile()
@@ -321,7 +340,7 @@ void VoglEditor::playCurrentTraceFile()
 
 void VoglEditor::trimCurrentTraceFile()
 {
-    trim_trace_file(m_openFilename, static_cast<uint>(m_pTraceReader->get_max_frame_index()), 200);
+    trim_trace_file(m_openFilename, static_cast<uint>(m_pTraceReader->get_max_frame_index()), g_settings.trim_large_trace_prompt_size());
 }
 
 /// \return True if the new trim file is now open in the editor
@@ -1027,14 +1046,14 @@ bool VoglEditor::open_trace_file(dynamic_string filename)
        m_pStatusLabel->clear();
    }
 
-   if (tmpReader->get_max_frame_index() > 200)
+   if (tmpReader->get_max_frame_index() > g_settings.trim_large_trace_prompt_size())
    {
        int ret = QMessageBox::warning(this, tr(g_PROJECT_NAME.toStdString().c_str()), tr("The loaded trace file has many frames and debugging may be difficult.\nWould you like to trim the trace?"),
                             QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
 
        if (ret == QMessageBox::Yes)
        {
-           if (trim_trace_file(filename.c_str(), static_cast<uint>(tmpReader->get_max_frame_index()), 200))
+           if (trim_trace_file(filename.c_str(), static_cast<uint>(tmpReader->get_max_frame_index()), g_settings.trim_large_trace_prompt_size()))
            {
                // user decided to open the new trim file, and the UI should already be updated
                // clean up here and return
diff --git a/src/vogleditor/vogleditor_settings.cpp b/src/vogleditor/vogleditor_settings.cpp
new file mode 100644 (file)
index 0000000..84d12b9
--- /dev/null
@@ -0,0 +1,120 @@
+#include "vogleditor_settings.h"
+#include "vogl_common.h"
+#include "vogl_file_utils.h"
+
+static const unsigned int VOGLEDITOR_SETTINGS_FILE_FORMAT_VERSION_1 = 1;
+static const unsigned int VOGLEDITOR_SETTINGS_FILE_FORMAT_VERSION = VOGLEDITOR_SETTINGS_FILE_FORMAT_VERSION_1;
+
+vogleditor_settings::vogleditor_settings()
+    : m_file_format_version(VOGLEDITOR_SETTINGS_FILE_FORMAT_VERSION_1)
+{
+    m_defaults.trim_large_trace_prompt_size = 200;
+    m_defaults.window_position_left = 0;
+    m_defaults.window_position_top = 0;
+    m_defaults.window_size_width = 1024;
+    m_defaults.window_size_height = 768;
+
+    m_settings = m_defaults;
+}
+
+dynamic_string vogleditor_settings::get_settings_path(const char* settingsFilename)
+{
+    dynamic_string settingsPath;
+    const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
+    const char* home = getenv("HOME");
+    if (xdgConfigHome != NULL && strlen(xdgConfigHome) != 0)
+    {
+        settingsPath = xdgConfigHome;
+        settingsPath += "/vogleditor/";
+        if (vogl::file_utils::does_dir_exist(settingsPath.c_str()) == false)
+        {
+            if (vogl::file_utils::create_directories_from_full_path(settingsPath) == false)
+            {
+                VOGL_ASSERT(!"Failed to create directories for settings file.");
+            }
+        }
+    }
+    else if (home != NULL && strlen(home) != 0)
+    {
+        settingsPath += home;
+        settingsPath += "/.config/vogleditor/";
+        if (vogl::file_utils::does_dir_exist(settingsPath.c_str())== false)
+        {
+            if (vogl::file_utils::create_directories_from_full_path(settingsPath) == false)
+            {
+                VOGL_ASSERT(!"Failed to create directories for settings file.");
+            }
+        }
+    }
+    else
+    {
+        // the settings file will end up in the current working directory
+    }
+
+    settingsPath += settingsFilename;
+    return settingsPath;
+}
+
+bool vogleditor_settings::load(const char* settingsFile)
+{
+    bool bLoaded = false;
+    json_document settingsDoc;
+    dynamic_string path = get_settings_path(settingsFile);
+    if (settingsDoc.deserialize_file(path.c_str()))
+    {
+        // validate metadata
+        json_node* pMetadata = settingsDoc.get_root()->find_child_object("metadata");
+        if (pMetadata == NULL)
+        {
+            return false;
+        }
+
+        const json_value& rFormatVersion = pMetadata->find_value("vogleditor_settings_file_format_version");
+        if (!rFormatVersion.is_valid() || rFormatVersion.as_uint32() != VOGLEDITOR_SETTINGS_FILE_FORMAT_VERSION_1)
+        {
+            return false;
+        }
+
+        m_file_format_version = rFormatVersion.as_uint32(VOGLEDITOR_SETTINGS_FILE_FORMAT_VERSION);
+
+        // validate that settings node exists
+        json_node* pSettingsNode = settingsDoc.get_root()->find_child_object("settings");
+        if (pSettingsNode == NULL)
+        {
+            return false;
+        }
+
+        // if so, consider the file successfully loaded
+        bLoaded = true;
+
+        // all settings should be considered optional, if they are not in the file, then the default value is used
+        m_settings.trim_large_trace_prompt_size = pSettingsNode->value_as_uint32("trim_large_trace_prompt_size", m_defaults.trim_large_trace_prompt_size);
+
+        m_settings.window_position_left = pSettingsNode->value_as_int("window_position_left", m_defaults.window_position_left);
+        m_settings.window_position_top = pSettingsNode->value_as_int("window_position_top", m_defaults.window_position_top);
+        m_settings.window_size_width = pSettingsNode->value_as_int("window_size_width", m_defaults.window_size_width);
+        m_settings.window_size_height = pSettingsNode->value_as_int("window_size_height", m_defaults.window_size_height);
+    }
+
+    return bLoaded;
+}
+
+bool vogleditor_settings::save(const char* settingsFile)
+{
+    json_document settingsDoc;
+    json_node& metadata = settingsDoc.get_root()->add_object("metadata");
+    metadata.add_key_value("vogleditor_settings_file_format_version", to_hex_string(VOGLEDITOR_SETTINGS_FILE_FORMAT_VERSION));
+
+    // settings
+    json_node& settings = settingsDoc.get_root()->add_object("settings");
+    settings.add_key_value("trim_large_trace_prompt_size", m_settings.trim_large_trace_prompt_size);
+
+    settings.add_key_value("window_position_left", m_settings.window_position_left);
+    settings.add_key_value("window_position_top", m_settings.window_position_top);
+    settings.add_key_value("window_size_width", m_settings.window_size_width);
+    settings.add_key_value("window_size_height", m_settings.window_size_height);
+
+    dynamic_string path = get_settings_path(settingsFile);
+    bool bSavedSuccessfully = settingsDoc.serialize_to_file(path.c_str());
+    return bSavedSuccessfully;
+}
diff --git a/src/vogleditor/vogleditor_settings.h b/src/vogleditor/vogleditor_settings.h
new file mode 100644 (file)
index 0000000..3da7a75
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef VOGLEDITOR_SETTINGS_H
+#define VOGLEDITOR_SETTINGS_H
+
+#include "vogl_dynamic_string.h"
+
+struct vogleditor_setting_struct
+{
+    int window_position_left;
+    int window_position_top;
+    int window_size_width;
+    int window_size_height;
+    unsigned int trim_large_trace_prompt_size;
+};
+
+class vogleditor_settings
+{
+public:
+    vogleditor_settings();
+    virtual ~vogleditor_settings() {}
+
+    bool load(const char* settingsFile);
+    bool save(const char* settingsFile);
+
+    int window_position_left() { return m_settings.window_position_left; }
+    int window_position_top() { return m_settings.window_position_top; }
+    int window_size_width() { return m_settings.window_size_width; }
+    int window_size_height() { return m_settings.window_size_height; }
+    void set_window_position_left(int window_position_left) { m_settings.window_position_left = window_position_left; }
+    void set_window_position_top(int window_position_top) { m_settings.window_position_top = window_position_top; }
+    void set_window_size_width(int window_size_width) { m_settings.window_size_width = window_size_width; }
+    void set_window_size_height(int window_size_height) { m_settings.window_size_height = window_size_height; }
+
+    unsigned int trim_large_trace_prompt_size() { return m_settings.trim_large_trace_prompt_size; }
+    void set_trim_large_trace_prompt_size(unsigned int trim_large_trace_prompt_size) { m_settings.trim_large_trace_prompt_size = trim_large_trace_prompt_size; }
+
+private:
+    unsigned int m_file_format_version;
+    vogleditor_setting_struct m_settings;
+    vogleditor_setting_struct m_defaults;
+
+    vogl::dynamic_string get_settings_path(const char* settingsFilename);
+};
+
+#endif // VOGLEDITOR_SETTINGS_H