wxWidgets based Stable Diffusion C++ GUi
Ferenc Szontágh
2024-02-04 5e5b8dcd5ce488ec4fdcb5ff07272830711566de
random seed on gui, context menu into tables
7 files modified
1 files added
1090 ■■■■■ changed files
.vscode/settings.json 3 ●●●● patch | view | raw | blame | history
ui/MainWindow.cpp 56 ●●●●● patch | view | raw | blame | history
ui/MainWindow.h 10 ●●●●● patch | view | raw | blame | history
ui/MainWindowUI.cpp 526 ●●●● patch | view | raw | blame | history
ui/MainWindowUI.h 5 ●●●● patch | view | raw | blame | history
ui/QueueManager.cpp 4 ●●●● patch | view | raw | blame | history
ui/icons/16/dice_four.png patch | view | raw | blame | history
ui/windows.fbp 486 ●●●●● patch | view | raw | blame | history
.vscode/settings.json
@@ -111,5 +111,6 @@
        "logging": {
            "trace": true
        }
    }
    },
    "breadcrumbs.symbolSortOrder": "name"
}
ui/MainWindow.cpp
@@ -8,6 +8,7 @@
#include "MainWindow.h"
#include "../../sd.cpp.ui2/ui/embended_files/cube.png.h"
#include "../../sd.cpp.ui2/ui/embended_files/dice_four.png.h"
#include "../../sd.cpp.ui2/ui/embended_files/disk.png.h"
#include "../../sd.cpp.ui2/ui/embended_files/file_import.png.h"
#include "../../sd.cpp.ui2/ui/embended_files/forward.png.h"
@@ -87,36 +88,21 @@
    wxBoxSizer* sizer0003;
    sizer0003 = new wxBoxSizer( wxHORIZONTAL );
    m_staticText231 = new wxStaticText( m_all_panel, wxID_ANY, wxT("CFG:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_staticText231->Wrap( 0 );
    sizer0003->Add( m_staticText231, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
    m_cfg = new wxSpinCtrlDouble( m_all_panel, wxID_ANY, wxT("7.0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 15, 0, 0.1 );
    m_cfg->SetDigits( 1 );
    m_cfg->SetMinSize( wxSize( 45,-1 ) );
    sizer0003->Add( m_cfg, 0, wxALL, 5 );
    m_staticText233 = new wxStaticText( m_all_panel, wxID_ANY, wxT("Seed:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_staticText233->Wrap( 0 );
    sizer0003->Add( m_staticText233, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
    m_seed = new wxSpinCtrl( m_all_panel, wxID_ANY, wxT("44"), wxDefaultPosition, wxDefaultSize, 0, -1, 99999999999, 44 );
    m_seed->SetMinSize( wxSize( 80,-1 ) );
    m_seed->SetMinSize( wxSize( 110,-1 ) );
    sizer0003->Add( m_seed, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
    m_staticText234 = new wxStaticText( m_all_panel, wxID_ANY, wxT("Clip skip:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_staticText234->Wrap( 0 );
    m_staticText234->SetToolTip( wxT("ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1)\n<= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x") );
    m_random_seed = new wxButton( m_all_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 24,24 ), 0 );
    sizer0003->Add( m_staticText234, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
    m_random_seed->SetBitmap( dice_four_png_to_wx_bitmap() );
    m_random_seed->SetToolTip( wxT("Generate random seed") );
    m_clip_skip = new wxSpinCtrl( m_all_panel, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -1, 2, 0 );
    m_clip_skip->SetToolTip( wxT("ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1)\n<= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x") );
    m_clip_skip->SetMinSize( wxSize( 45,-1 ) );
    sizer0003->Add( m_clip_skip, 0, wxALL, 5 );
    sizer0003->Add( m_random_seed, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
    m_staticText14 = new wxStaticText( m_all_panel, wxID_ANY, wxT("Steps:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_staticText14->Wrap( -1 );
@@ -156,6 +142,34 @@
    sizer0002->Add( sizer0003, 0, wxALL|wxEXPAND, 5 );
    wxBoxSizer* bSizer22;
    bSizer22 = new wxBoxSizer( wxHORIZONTAL );
    m_staticText231 = new wxStaticText( m_all_panel, wxID_ANY, wxT("CFG:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_staticText231->Wrap( 0 );
    bSizer22->Add( m_staticText231, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
    m_cfg = new wxSpinCtrlDouble( m_all_panel, wxID_ANY, wxT("7.0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 15, 0, 0.1 );
    m_cfg->SetDigits( 1 );
    m_cfg->SetMinSize( wxSize( 45,-1 ) );
    bSizer22->Add( m_cfg, 0, wxALL, 5 );
    m_staticText234 = new wxStaticText( m_all_panel, wxID_ANY, wxT("Clip skip:"), wxDefaultPosition, wxDefaultSize, 0 );
    m_staticText234->Wrap( 0 );
    m_staticText234->SetToolTip( wxT("ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1)\n<= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x") );
    bSizer22->Add( m_staticText234, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
    m_clip_skip = new wxSpinCtrl( m_all_panel, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -1, 2, 0 );
    m_clip_skip->SetToolTip( wxT("ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1)\n<= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x") );
    m_clip_skip->SetMinSize( wxSize( 45,-1 ) );
    bSizer22->Add( m_clip_skip, 0, wxALL, 5 );
    sizer0002->Add( bSizer22, 0, wxEXPAND|wxALL, 5 );
    m_notebook1302 = new wxNotebook( m_all_panel, wxID_ANY, wxDefaultPosition, wxSize( -1,200 ), wxBK_DEFAULT );
    m_notebook1302->SetMinSize( wxSize( -1,200 ) );
@@ -334,6 +348,7 @@
    m_refresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onModelsRefresh ), NULL, this );
    m_model->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( UI::onModelSelect ), NULL, this );
    m_vae->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( UI::onVaeSelect ), NULL, this );
    m_random_seed->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onRandomGenerateButton ), NULL, this );
    m_button7->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onResolutionSwap ), NULL, this );
    m_start_jobs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onJobsStart ), NULL, this );
    m_pause_jobs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onJobsPause ), NULL, this );
@@ -357,6 +372,7 @@
    m_refresh->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onModelsRefresh ), NULL, this );
    m_model->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( UI::onModelSelect ), NULL, this );
    m_vae->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( UI::onVaeSelect ), NULL, this );
    m_random_seed->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onRandomGenerateButton ), NULL, this );
    m_button7->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onResolutionSwap ), NULL, this );
    m_start_jobs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onJobsStart ), NULL, this );
    m_pause_jobs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( UI::onJobsPause ), NULL, this );
ui/MainWindow.h
@@ -51,12 +51,9 @@
        wxChoice* m_model;
        wxStaticText* m_staticText161;
        wxChoice* m_vae;
        wxStaticText* m_staticText231;
        wxSpinCtrlDouble* m_cfg;
        wxStaticText* m_staticText233;
        wxSpinCtrl* m_seed;
        wxStaticText* m_staticText234;
        wxSpinCtrl* m_clip_skip;
        wxButton* m_random_seed;
        wxStaticText* m_staticText14;
        wxSpinCtrl* m_steps;
        wxStaticLine* m_staticLine236;
@@ -65,6 +62,10 @@
        wxStaticText* m_staticText239;
        wxSpinCtrl* m_height;
        wxButton* m_button7;
        wxStaticText* m_staticText231;
        wxSpinCtrlDouble* m_cfg;
        wxStaticText* m_staticText234;
        wxSpinCtrl* m_clip_skip;
        wxNotebook* m_notebook1302;
        wxPanel* m_jobs_panel;
        wxButton* m_start_jobs;
@@ -97,6 +98,7 @@
        virtual void onModelsRefresh( wxCommandEvent& event ) { event.Skip(); }
        virtual void onModelSelect( wxCommandEvent& event ) { event.Skip(); }
        virtual void onVaeSelect( wxCommandEvent& event ) { event.Skip(); }
        virtual void onRandomGenerateButton( wxCommandEvent& event ) { event.Skip(); }
        virtual void onResolutionSwap( wxCommandEvent& event ) { event.Skip(); }
        virtual void onJobsStart( wxCommandEvent& event ) { event.Skip(); }
        virtual void onJobsPause( wxCommandEvent& event ) { event.Skip(); }
ui/MainWindowUI.cpp
@@ -105,6 +105,11 @@
    }
}
void MainWindowUI::onRandomGenerateButton(wxCommandEvent &event)
{
    this->m_seed->SetValue(sd_gui_utils::generateRandomInt(100000000, 999999999));
}
void MainWindowUI::onResolutionSwap(wxCommandEvent &event)
{
    auto oldW = this->m_width->GetValue();
@@ -137,10 +142,27 @@
void MainWindowUI::onContextMenu(wxDataViewEvent &event)
{
    auto *source = (wxDataViewListCtrl *)event.GetEventObject();
    wxMenu menu;
    menu.Append(0, "Calculate Hash");
    menu.Append(1, "Download info from CivitAi.com");
    menu.SetClientData((void *)source);
    if (source == this->m_joblist)
    {
        menu.Append(1, "Copy and restart");
        menu.Append(2, "Copy paramters to text2img");
        menu.Append(3, "Copy paramters to img2img");
        menu.Append(4, "Details...");
    }
    if (source == this->m_data_model_list)
    {
        menu.Append(1, "Calculate Hash");
        menu.Append(2, "Download info from CivitAi.com");
    }
    menu.Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindowUI::OnPopupClick), NULL, this);
    PopupMenu(&menu);
}
@@ -280,99 +302,178 @@
    }
}
void MainWindowUI::HandleSDLog(sd_log_level_t level, const char *text, void *data)
void MainWindowUI::LoadFileList(sd_gui_utils::DirTypes type)
{
    if (level == sd_log_level_t::SD_LOG_INFO || level == sd_log_level_t::SD_LOG_ERROR)
    std::string basepath;
    switch (type)
    {
        auto *eventHandler = (wxEvtHandler *)data;
        wxThreadEvent *e = new wxThreadEvent();
        e->SetString(wxString::Format("SD_MESSAGE:%s", text));
        e->SetPayload(level);
        wxQueueEvent(eventHandler, e);
    case sd_gui_utils::DirTypes::VAE:
        this->VaeFiles.clear();
        this->m_vae->Clear();
        this->m_vae->Append("-none-");
        this->m_vae->Select(0);
        basepath = this->cfg->vae;
        break;
    case sd_gui_utils::DirTypes::LORA:
        basepath = this->cfg->lora;
        break;
    case sd_gui_utils::DirTypes::CHECKPOINT:
        this->ModelFiles.clear();
        this->m_model->Clear();
        this->m_model->Append("-none-");
        this->m_model->Select(0);
        basepath = this->cfg->model;
        break;
    case sd_gui_utils::DirTypes::PRESETS:
        this->Presets.clear();
        this->m_preset_list->Clear();
        this->m_preset_list->Append("-none-");
        this->m_preset_list->Select(0);
        basepath = this->cfg->presets;
        break;
    }
    if (!std::filesystem::exists(basepath))
    {
        std::filesystem::create_directories(basepath);
    }
    int i = 0;
    for (auto const &dir_entry : std::filesystem::recursive_directory_iterator(basepath))
    {
        if (!dir_entry.exists() || !dir_entry.is_regular_file() || !dir_entry.path().has_extension())
        {
            continue;
        }
        std::filesystem::path path = dir_entry.path();
        std::string ext = path.extension().string();
        if (type == sd_gui_utils::DirTypes::CHECKPOINT || type == sd_gui_utils::DirTypes::VAE)
        {
            if (ext != ".safetensors" && ext != ".ckpt")
            {
                continue;
            }
        }
        if (type == sd_gui_utils::DirTypes::PRESETS)
        {
            if (ext != ".json")
            {
                continue;
            }
        }
        std::string name = path.filename().replace_extension("").string();
        // prepend the subdirectory to the modelname
        // // wxFileName::GetPathSeparator()
        auto path_name = path.string();
        sd_gui_utils::replace(path_name, basepath, "");
        sd_gui_utils::replace(path_name, "//", "");
        sd_gui_utils::replace(path_name, "\\\\", "");
        sd_gui_utils::replace(path_name, ext, "");
        name = path_name.substr(1);
        if (type == sd_gui_utils::CHECKPOINT)
        {
            this->m_model->Append(name);
            this->ModelFiles.emplace(name, dir_entry.path().string());
        }
        if (type == sd_gui_utils::VAE)
        {
            this->m_vae->Append(name);
            this->VaeFiles.emplace(name, dir_entry.path().string());
        }
        if (type == sd_gui_utils::PRESETS)
        {
            sd_gui_utils::generator_preset preset;
            std::ifstream f(path.string());
            try
            {
                nlohmann::json data = nlohmann::json::parse(f);
                preset = data;
                preset.path = path.string();
                this->m_preset_list->Append(preset.name);
                this->Presets.emplace(preset.name, preset);
            }
            catch (const std::exception &e)
            {
                std::remove(path.string().c_str());
                std::cerr << e.what() << '\n';
            }
        }
    }
    if (type == sd_gui_utils::CHECKPOINT)
    {
        this->logs->AppendText(fmt::format("Loaded checkpoints: {}\n", this->ModelFiles.size()));
    }
    if (type == sd_gui_utils::VAE)
    {
        this->logs->AppendText(fmt::format("Loaded vaes: {}\n", this->VaeFiles.size()));
    }
    if (type == sd_gui_utils::PRESETS)
    {
        this->logs->AppendText(fmt::format("Loaded presets: {}\n", this->Presets.size()));
        if (this->Presets.size() > 0)
        {
            this->m_preset_list->Enable();
        }
    }
}
void MainWindowUI::OnQueueItemManagerItemStatusChanged(QM::QueueItem item)
void MainWindowUI::OnQueueItemManagerItemAdded(QM::QueueItem item)
{
    wxVector<wxVariant> data;
    auto created_at = sd_gui_utils::formatUnixTimestampToDate(item.created_at);
    data.push_back(wxVariant(std::to_string(item.id)));
    data.push_back(wxVariant(created_at));
    data.push_back(wxVariant(item.model));
    data.push_back(wxVariant(sd_gui_utils::sample_method_str[(int)item.params.sample_method]));
    data.push_back(wxVariant(std::to_string(item.params.seed)));
    data.push_back(item.status == QM::QueueStatus::DONE ? 100 : 1); // progressbar
    data.push_back(wxString("-.--it/s"));                           // speed
    data.push_back(wxVariant(QM::QueueStatus_str[item.status]));    // status
    auto store = this->m_joblist->GetStore();
    int lastCol = this->m_joblist->GetColumnCount() - 1;
    QM::QueueItem *nItem = new QM::QueueItem(item);
    for (unsigned int i = 0; i < store->GetItemCount(); i++)
    this->JobTableItems[item.id] = nItem;
    //  store->AppendItem(data, wxUIntPtr(this->JobTableItems[item.id]));
    store->PrependItem(data, wxUIntPtr(this->JobTableItems[item.id]));
}
MainWindowUI::~MainWindowUI()
{
    // this->Hide();
    /* for (int i = 0; i < this->threads.size(); i++)
       {
           if (this->threads.at(i).joinable())
           {
               this->threads.at(i).join();
           }
       }*/
    for (auto &t : this->threads)
    {
        auto _item = store->GetItem(i);
        auto _item_data = store->GetItemData(_item);
        auto *_qitem = reinterpret_cast<QM::QueueItem *>(_item_data);
        if (_qitem->id == item.id)
        {
            store->SetValueByRow(wxVariant(QM::QueueStatus_str[item.status]), i, lastCol);
            this->m_joblist->Refresh();
            break;
        }
        t->join();
    }
}
void MainWindowUI::loadModelList()
void MainWindowUI::loadVaeList()
{
    this->m_sampler->Clear();
    for (auto sampler : sd_gui_utils::sample_method_str)
    if (!std::filesystem::exists(this->cfg->vae))
    {
        int _u = this->m_sampler->Append(sampler);
        if (sampler == sd_gui_utils::sample_method_str[this->sd_params->sample_method])
        {
            this->m_sampler->Select(_u);
        }
        std::filesystem::create_directories(this->cfg->vae);
    }
    this->LoadFileList(sd_gui_utils::DirTypes::CHECKPOINT);
    for (auto model : this->ModelFiles)
    {
        // auto size = sd_gui_utils::HumanReadable{std::filesystem::file_size(model.second)};
        uintmax_t size = std::filesystem::file_size(model.second);
        auto humanSize = sd_gui_utils::humanReadableFileSize(size);
        auto hs = wxString::Format("%.1f %s", humanSize.first, humanSize.second);
        wxVector<wxVariant> data;
        data.push_back(wxVariant(model.first));
        data.push_back(hs);
        data.push_back("--");
        this->m_data_model_list->AppendItem(data);
    }
    this->m_data_model_list->Refresh();
    this->LoadFileList(sd_gui_utils::DirTypes::VAE);
}
void MainWindowUI::StartGeneration(QM::QueueItem myJob)
void MainWindowUI::OnQueueItemManagerItemUpdated(QM::QueueItem item)
{
    // here starts the trhead
    // this->threads.push_back(std::thread(std::bind(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob)));
    // this->threads.emplace_back(std::thread(std::bind(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob)));
    // this->threads.emplace_back(std::thread(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob));
    std::thread(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob);
}
void MainWindowUI::HandleSDProgress(int step, int steps, float time, void *data)
{
    sd_gui_utils::VoidHolder *objs = (sd_gui_utils::VoidHolder *)data;
    wxEvtHandler *eventHandler = (wxEvtHandler *)objs->p1;
    QM::QueueItem *myItem = (QM::QueueItem *)objs->p2;
    myItem->step = step;
    myItem->steps = steps;
    myItem->time = time;
    /*
        format it/s
        time > 1.0f ? "\r%s %i/%i - %.2fs/it" : "\r%s %i/%i - %.2fit/s",
               progress.c_str(), step, steps,
               time > 1.0f || time == 0 ? time : (1.0f / time)
    */
    wxThreadEvent *e = new wxThreadEvent();
    e->SetString(wxString::Format("GENERATION_PROGRESS:%d/%d", step, steps));
    e->SetPayload(myItem);
    wxQueueEvent(eventHandler, e);
}
void MainWindowUI::Generate(wxEvtHandler *eventHandler, QM::QueueItem myItem)
@@ -556,6 +657,109 @@
{
    this->initConfig();
    this->settingsWindow->Destroy();
}
void MainWindowUI::OnPopupClick(wxCommandEvent &evt)
{
    void *data = static_cast<wxMenu *>(evt.GetEventObject())->GetClientData();
}
void MainWindowUI::HandleSDLog(sd_log_level_t level, const char *text, void *data)
{
    if (level == sd_log_level_t::SD_LOG_INFO || level == sd_log_level_t::SD_LOG_ERROR)
    {
        auto *eventHandler = (wxEvtHandler *)data;
        wxThreadEvent *e = new wxThreadEvent();
        e->SetString(wxString::Format("SD_MESSAGE:%s", text));
        e->SetPayload(level);
        wxQueueEvent(eventHandler, e);
    }
}
void MainWindowUI::OnQueueItemManagerItemStatusChanged(QM::QueueItem item)
{
    auto store = this->m_joblist->GetStore();
    int lastCol = this->m_joblist->GetColumnCount() - 1;
    for (unsigned int i = 0; i < store->GetItemCount(); i++)
    {
        auto _item = store->GetItem(i);
        auto _item_data = store->GetItemData(_item);
        auto *_qitem = reinterpret_cast<QM::QueueItem *>(_item_data);
        if (_qitem->id == item.id)
        {
            store->SetValueByRow(wxVariant(QM::QueueStatus_str[item.status]), i, lastCol);
            this->m_joblist->Refresh();
            break;
        }
    }
}
void MainWindowUI::loadModelList()
{
    this->m_sampler->Clear();
    for (auto sampler : sd_gui_utils::sample_method_str)
    {
        int _u = this->m_sampler->Append(sampler);
        if (sampler == sd_gui_utils::sample_method_str[this->sd_params->sample_method])
        {
            this->m_sampler->Select(_u);
        }
    }
    this->LoadFileList(sd_gui_utils::DirTypes::CHECKPOINT);
    for (auto model : this->ModelFiles)
    {
        // auto size = sd_gui_utils::HumanReadable{std::filesystem::file_size(model.second)};
        uintmax_t size = std::filesystem::file_size(model.second);
        auto humanSize = sd_gui_utils::humanReadableFileSize(size);
        auto hs = wxString::Format("%.1f %s", humanSize.first, humanSize.second);
        wxVector<wxVariant> data;
        data.push_back(wxVariant(model.first));
        data.push_back(hs);
        data.push_back("--");
        this->m_data_model_list->AppendItem(data);
    }
    this->m_data_model_list->Refresh();
}
void MainWindowUI::StartGeneration(QM::QueueItem myJob)
{
    // here starts the trhead
    // this->threads.push_back(std::thread(std::bind(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob)));
    // this->threads.emplace_back(std::thread(std::bind(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob)));
    // this->threads.emplace_back(std::thread(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob));
    // std::thread j(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob);
    // std::thread *p(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob);
    std::thread *p = new std::thread(&MainWindowUI::Generate, this, this->GetEventHandler(), myJob);
    this->threads.emplace_back(p);
}
void MainWindowUI::HandleSDProgress(int step, int steps, float time, void *data)
{
    sd_gui_utils::VoidHolder *objs = (sd_gui_utils::VoidHolder *)data;
    wxEvtHandler *eventHandler = (wxEvtHandler *)objs->p1;
    QM::QueueItem *myItem = (QM::QueueItem *)objs->p2;
    myItem->step = step;
    myItem->steps = steps;
    myItem->time = time;
    /*
        format it/s
        time > 1.0f ? "\r%s %i/%i - %.2fs/it" : "\r%s %i/%i - %.2fit/s",
               progress.c_str(), step, steps,
               time > 1.0f || time == 0 ? time : (1.0f / time)
    */
    wxThreadEvent *e = new wxThreadEvent();
    e->SetString(wxString::Format("GENERATION_PROGRESS:%d/%d", step, steps));
    e->SetPayload(myItem);
    wxQueueEvent(eventHandler, e);
}
void MainWindowUI::OnThreadMessage(wxThreadEvent &e)
@@ -820,174 +1024,4 @@
void MainWindowUI::LoadPresets()
{
    this->LoadFileList(sd_gui_utils::DirTypes::PRESETS);
}
void MainWindowUI::OnQueueItemManagerItemUpdated(QM::QueueItem item)
{
}
void MainWindowUI::loadVaeList()
{
    if (!std::filesystem::exists(this->cfg->vae))
    {
        std::filesystem::create_directories(this->cfg->vae);
    }
    this->LoadFileList(sd_gui_utils::DirTypes::VAE);
}
MainWindowUI::~MainWindowUI()
{
    // this->Hide();
    for (int i = 0; i < this->threads.size(); i++)
    {
        if (this->threads.at(i).joinable())
        {
            this->threads.at(i).join();
        }
    }
}
void MainWindowUI::OnQueueItemManagerItemAdded(QM::QueueItem item)
{
    wxVector<wxVariant> data;
    auto created_at = sd_gui_utils::formatUnixTimestampToDate(item.created_at);
    data.push_back(wxVariant(std::to_string(item.id)));
    data.push_back(wxVariant(created_at));
    data.push_back(wxVariant(item.model));
    data.push_back(wxVariant(sd_gui_utils::sample_method_str[(int)item.params.sample_method]));
    data.push_back(wxVariant(std::to_string(item.params.seed)));
    data.push_back(item.status == QM::QueueStatus::DONE ? 100 : 1); // progressbar
    data.push_back(wxString("-.--it/s"));                           // speed
    data.push_back(wxVariant(QM::QueueStatus_str[item.status]));    // status
    auto store = this->m_joblist->GetStore();
    QM::QueueItem *nItem = new QM::QueueItem(item);
    this->JobTableItems[item.id] = nItem;
    //  store->AppendItem(data, wxUIntPtr(this->JobTableItems[item.id]));
    store->PrependItem(data, wxUIntPtr(this->JobTableItems[item.id]));
}
void MainWindowUI::LoadFileList(sd_gui_utils::DirTypes type)
{
    std::string basepath;
    switch (type)
    {
    case sd_gui_utils::DirTypes::VAE:
        this->VaeFiles.clear();
        this->m_vae->Clear();
        this->m_vae->Append("-none-");
        this->m_vae->Select(0);
        basepath = this->cfg->vae;
        break;
    case sd_gui_utils::DirTypes::LORA:
        basepath = this->cfg->lora;
        break;
    case sd_gui_utils::DirTypes::CHECKPOINT:
        this->ModelFiles.clear();
        this->m_model->Clear();
        this->m_model->Append("-none-");
        this->m_model->Select(0);
        basepath = this->cfg->model;
        break;
    case sd_gui_utils::DirTypes::PRESETS:
        this->Presets.clear();
        this->m_preset_list->Clear();
        this->m_preset_list->Append("-none-");
        this->m_preset_list->Select(0);
        basepath = this->cfg->presets;
        break;
    }
    if (!std::filesystem::exists(basepath))
    {
        std::filesystem::create_directories(basepath);
    }
    int i = 0;
    for (auto const &dir_entry : std::filesystem::recursive_directory_iterator(basepath))
    {
        if (!dir_entry.exists() || !dir_entry.is_regular_file() || !dir_entry.path().has_extension())
        {
            continue;
        }
        std::filesystem::path path = dir_entry.path();
        std::string ext = path.extension().string();
        if (type == sd_gui_utils::DirTypes::CHECKPOINT || type == sd_gui_utils::DirTypes::VAE)
        {
            if (ext != ".safetensors" && ext != ".ckpt")
            {
                continue;
            }
        }
        if (type == sd_gui_utils::DirTypes::PRESETS)
        {
            if (ext != ".json")
            {
                continue;
            }
        }
        std::string name = path.filename().replace_extension("").string();
        // prepend the subdirectory to the modelname
        // // wxFileName::GetPathSeparator()
        auto path_name = path.string();
        sd_gui_utils::replace(path_name, basepath, "");
        sd_gui_utils::replace(path_name, "//", "");
        sd_gui_utils::replace(path_name, "\\\\", "");
        sd_gui_utils::replace(path_name, ext, "");
        name = path_name.substr(1);
        if (type == sd_gui_utils::CHECKPOINT)
        {
            this->m_model->Append(name);
            this->ModelFiles.emplace(name, dir_entry.path().string());
        }
        if (type == sd_gui_utils::VAE)
        {
            this->m_vae->Append(name);
            this->VaeFiles.emplace(name, dir_entry.path().string());
        }
        if (type == sd_gui_utils::PRESETS)
        {
            sd_gui_utils::generator_preset preset;
            std::ifstream f(path.string());
            try
            {
                nlohmann::json data = nlohmann::json::parse(f);
                preset = data;
                preset.path = path.string();
                this->m_preset_list->Append(preset.name);
                this->Presets.emplace(preset.name, preset);
            }
            catch (const std::exception &e)
            {
                std::remove(path.string().c_str());
                std::cerr << e.what() << '\n';
            }
        }
    }
    if (type == sd_gui_utils::CHECKPOINT)
    {
        this->logs->AppendText(fmt::format("Loaded checkpoints: {}\n", this->ModelFiles.size()));
    }
    if (type == sd_gui_utils::VAE)
    {
        this->logs->AppendText(fmt::format("Loaded vaes: {}\n", this->VaeFiles.size()));
    }
    if (type == sd_gui_utils::PRESETS)
    {
        this->logs->AppendText(fmt::format("Loaded presets: {}\n", this->Presets.size()));
        if (this->Presets.size() > 0)
        {
            this->m_preset_list->Enable();
        }
    }
}
ui/MainWindowUI.h
@@ -41,6 +41,7 @@
        void onModelsRefresh( wxCommandEvent& event );
        void onModelSelect( wxCommandEvent& event );
        void onVaeSelect( wxCommandEvent& event );
        void onRandomGenerateButton( wxCommandEvent& event );
        void onResolutionSwap( wxCommandEvent& event );
        void onJobsStart( wxCommandEvent& event );
        void onJobsPause( wxCommandEvent& event );
@@ -79,7 +80,7 @@
    std::string currentModel;
    sd_ctx_t *sd_ctx;
    std::streambuf *buffer;
    std::vector<std::thread> threads;
    std::vector<std::thread*> threads;
    // row,QueueItem
    std::map<int, QM::QueueItem*> JobTableItems;
@@ -89,6 +90,7 @@
    void loadModelList();
    void loadVaeList();
    void OnCloseSettings(wxCloseEvent &event);
    void OnPopupClick(wxCommandEvent &evt);
    void LoadFileList(sd_gui_utils::DirTypes type = sd_gui_utils::DirTypes::CHECKPOINT);
    void LoadPresets();
@@ -111,6 +113,7 @@
    wxNotificationMessage *notification;
};
#endif // __MainWindowUI__
ui/QueueManager.cpp
@@ -261,6 +261,10 @@
            {
                item.status = QM::QueueStatus::FAILED;
            }
            if (item.status == QM::QueueStatus::MODEL_LOADING)
            {
                item.status = QM::QueueStatus::FAILED;
            }
            this->AddItem(item);
        }
        catch (const std::exception &e)
ui/icons/16/dice_four.png
ui/windows.fbp
@@ -583,133 +583,6 @@
                      <property name="gripper">0</property>
                      <property name="hidden"></property>
                      <property name="id">wxID_ANY</property>
                      <property name="label">CFG:</property>
                      <property name="markup">0</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size"></property>
                      <property name="moveable">1</property>
                      <property name="name">m_staticText231</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="style"></property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip"></property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                      <property name="wrap">0</property>
                    </object>
                  </object>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxALL</property>
                    <property name="proportion">0</property>
                    <object class="wxSpinCtrlDouble" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="digits">1</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden">0</property>
                      <property name="id">wxID_ANY</property>
                      <property name="inc">0.1</property>
                      <property name="initial">0</property>
                      <property name="max">15</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min">0</property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size">45,-1</property>
                      <property name="moveable">1</property>
                      <property name="name">m_cfg</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="style">wxSP_ARROW_KEYS</property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip"></property>
                      <property name="value">7.0</property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                    </object>
                  </object>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
                    <property name="proportion">0</property>
                    <object class="wxStaticText" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden"></property>
                      <property name="id">wxID_ANY</property>
                      <property name="label">Seed:</property>
                      <property name="markup">0</property>
                      <property name="max_size"></property>
@@ -780,7 +653,7 @@
                      <property name="min">-1</property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size">80,-1</property>
                      <property name="minimum_size">110,-1</property>
                      <property name="moveable">1</property>
                      <property name="name">m_seed</property>
                      <property name="pane_border">1</property>
@@ -802,11 +675,11 @@
                      <property name="window_style"></property>
                    </object>
                  </object>
                  <object class="sizeritem" expanded="false">
                  <object class="sizeritem" expanded="true">
                    <property name="border">5</property>
                    <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
                    <property name="proportion">0</property>
                    <object class="wxStaticText" expanded="false">
                    <object class="wxButton" expanded="true">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
@@ -815,15 +688,20 @@
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="auth_needed">0</property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="bitmap">Load From Embedded File; icons/16/dice_four.png</property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="context_menu">0</property>
                      <property name="current"></property>
                      <property name="default">0</property>
                      <property name="default_pane">0</property>
                      <property name="disabled"></property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
@@ -831,11 +709,13 @@
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="focus"></property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden"></property>
                      <property name="hidden">0</property>
                      <property name="id">wxID_ANY</property>
                      <property name="label">Clip skip:</property>
                      <property name="label"></property>
                      <property name="margins"></property>
                      <property name="markup">0</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
@@ -844,87 +724,30 @@
                      <property name="minimize_button">0</property>
                      <property name="minimum_size"></property>
                      <property name="moveable">1</property>
                      <property name="name">m_staticText234</property>
                      <property name="name">m_random_seed</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="position"></property>
                      <property name="pressed"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="size">24,24</property>
                      <property name="style"></property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip">ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1)&#x0A;&lt;= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x</property>
                      <property name="tooltip">Generate random seed</property>
                      <property name="validator_data_type"></property>
                      <property name="validator_style">wxFILTER_NONE</property>
                      <property name="validator_type">wxDefaultValidator</property>
                      <property name="validator_variable"></property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                      <property name="wrap">0</property>
                    </object>
                  </object>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxALL</property>
                    <property name="proportion">0</property>
                    <object class="wxSpinCtrl" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden">0</property>
                      <property name="id">wxID_ANY</property>
                      <property name="initial">0</property>
                      <property name="max">2</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min">-1</property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size">45,-1</property>
                      <property name="moveable">1</property>
                      <property name="name">m_clip_skip</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="style">wxSP_ARROW_KEYS</property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip">ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1)&#x0A;&lt;= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x</property>
                      <property name="value">0</property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                      <event name="OnButtonClick">onRandomGenerateButton</event>
                    </object>
                  </object>
                  <object class="sizeritem" expanded="false">
@@ -1439,6 +1262,269 @@
                </object>
              </object>
              <object class="sizeritem" expanded="true">
                <property name="border">5</property>
                <property name="flag">wxEXPAND|wxALL</property>
                <property name="proportion">0</property>
                <object class="wxBoxSizer" expanded="true">
                  <property name="minimum_size"></property>
                  <property name="name">bSizer22</property>
                  <property name="orient">wxHORIZONTAL</property>
                  <property name="permission">none</property>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
                    <property name="proportion">0</property>
                    <object class="wxStaticText" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden"></property>
                      <property name="id">wxID_ANY</property>
                      <property name="label">CFG:</property>
                      <property name="markup">0</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size"></property>
                      <property name="moveable">1</property>
                      <property name="name">m_staticText231</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="style"></property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip"></property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                      <property name="wrap">0</property>
                    </object>
                  </object>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxALL</property>
                    <property name="proportion">0</property>
                    <object class="wxSpinCtrlDouble" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="digits">1</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden">0</property>
                      <property name="id">wxID_ANY</property>
                      <property name="inc">0.1</property>
                      <property name="initial">0</property>
                      <property name="max">15</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min">0</property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size">45,-1</property>
                      <property name="moveable">1</property>
                      <property name="name">m_cfg</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="style">wxSP_ARROW_KEYS</property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip"></property>
                      <property name="value">7.0</property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                    </object>
                  </object>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
                    <property name="proportion">0</property>
                    <object class="wxStaticText" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden"></property>
                      <property name="id">wxID_ANY</property>
                      <property name="label">Clip skip:</property>
                      <property name="markup">0</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size"></property>
                      <property name="moveable">1</property>
                      <property name="name">m_staticText234</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="style"></property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip">ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1)&#x0A;&lt;= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x</property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                      <property name="wrap">0</property>
                    </object>
                  </object>
                  <object class="sizeritem" expanded="false">
                    <property name="border">5</property>
                    <property name="flag">wxALL</property>
                    <property name="proportion">0</property>
                    <object class="wxSpinCtrl" expanded="false">
                      <property name="BottomDockable">1</property>
                      <property name="LeftDockable">1</property>
                      <property name="RightDockable">1</property>
                      <property name="TopDockable">1</property>
                      <property name="aui_layer"></property>
                      <property name="aui_name"></property>
                      <property name="aui_position"></property>
                      <property name="aui_row"></property>
                      <property name="best_size"></property>
                      <property name="bg"></property>
                      <property name="caption"></property>
                      <property name="caption_visible">1</property>
                      <property name="center_pane">0</property>
                      <property name="close_button">1</property>
                      <property name="context_help"></property>
                      <property name="context_menu">1</property>
                      <property name="default_pane">0</property>
                      <property name="dock">Dock</property>
                      <property name="dock_fixed">0</property>
                      <property name="docking">Left</property>
                      <property name="drag_accept_files">0</property>
                      <property name="enabled">1</property>
                      <property name="fg"></property>
                      <property name="floatable">1</property>
                      <property name="font"></property>
                      <property name="gripper">0</property>
                      <property name="hidden">0</property>
                      <property name="id">wxID_ANY</property>
                      <property name="initial">0</property>
                      <property name="max">2</property>
                      <property name="max_size"></property>
                      <property name="maximize_button">0</property>
                      <property name="maximum_size"></property>
                      <property name="min">-1</property>
                      <property name="min_size"></property>
                      <property name="minimize_button">0</property>
                      <property name="minimum_size">45,-1</property>
                      <property name="moveable">1</property>
                      <property name="name">m_clip_skip</property>
                      <property name="pane_border">1</property>
                      <property name="pane_position"></property>
                      <property name="pane_size"></property>
                      <property name="permission">protected</property>
                      <property name="pin_button">1</property>
                      <property name="pos"></property>
                      <property name="resize">Resizable</property>
                      <property name="show">1</property>
                      <property name="size"></property>
                      <property name="style">wxSP_ARROW_KEYS</property>
                      <property name="subclass">; ; forward_declare</property>
                      <property name="toolbar_pane">0</property>
                      <property name="tooltip">ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1)&#x0A;&lt;= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x</property>
                      <property name="value">0</property>
                      <property name="window_extra_style"></property>
                      <property name="window_name"></property>
                      <property name="window_style"></property>
                    </object>
                  </object>
                </object>
              </object>
              <object class="sizeritem" expanded="true">
                <property name="border">0</property>
                <property name="flag">wxALIGN_TOP|wxEXPAND</property>
                <property name="proportion">1</property>