From ede421dc3c37b255dfba9800737272e4c526b78d Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Thu, 3 Jul 2025 04:37:50 -0600 Subject: [PATCH 1/5] Working on notes icon display in the wxDataViewTree control #1552 --- api/include/SAM_FresnelPhysical.h | 2 ++ api/include/SAM_FresnelPhysicalIph.h | 2 ++ api/include/SAM_TroughPhysical.h | 2 ++ api/include/SAM_TroughPhysicalIph.h | 2 ++ api/modules/SAM_FresnelPhysical.cpp | 10 ++++++++++ api/modules/SAM_FresnelPhysicalIph.cpp | 10 ++++++++++ api/modules/SAM_TroughPhysical.cpp | 10 ++++++++++ api/modules/SAM_TroughPhysicalIph.cpp | 10 ++++++++++ src/casewin.cpp | 6 +++++- 9 files changed, 53 insertions(+), 1 deletion(-) diff --git a/api/include/SAM_FresnelPhysical.h b/api/include/SAM_FresnelPhysical.h index 138c210bb..4d605754f 100644 --- a/api/include/SAM_FresnelPhysical.h +++ b/api/include/SAM_FresnelPhysical.h @@ -2655,6 +2655,8 @@ extern "C" SAM_EXPORT double* SAM_FresnelPhysical_Outputs_rec_thermal_eff_aget(SAM_table ptr, int* length, SAM_error *err); + SAM_EXPORT double* SAM_FresnelPhysical_Outputs_rec_time_in_startup_aget(SAM_table ptr, int* length, SAM_error *err); + SAM_EXPORT double* SAM_FresnelPhysical_Outputs_recirculating_aget(SAM_table ptr, int* length, SAM_error *err); SAM_EXPORT double* SAM_FresnelPhysical_Outputs_rh_aget(SAM_table ptr, int* length, SAM_error *err); diff --git a/api/include/SAM_FresnelPhysicalIph.h b/api/include/SAM_FresnelPhysicalIph.h index 073c78369..8f9dfd16a 100644 --- a/api/include/SAM_FresnelPhysicalIph.h +++ b/api/include/SAM_FresnelPhysicalIph.h @@ -2713,6 +2713,8 @@ extern "C" SAM_EXPORT double* SAM_FresnelPhysicalIph_Outputs_rec_thermal_eff_aget(SAM_table ptr, int* length, SAM_error *err); + SAM_EXPORT double* SAM_FresnelPhysicalIph_Outputs_rec_time_in_startup_aget(SAM_table ptr, int* length, SAM_error *err); + SAM_EXPORT double* SAM_FresnelPhysicalIph_Outputs_recirculating_aget(SAM_table ptr, int* length, SAM_error *err); SAM_EXPORT double* SAM_FresnelPhysicalIph_Outputs_rh_aget(SAM_table ptr, int* length, SAM_error *err); diff --git a/api/include/SAM_TroughPhysical.h b/api/include/SAM_TroughPhysical.h index 2b838746c..2aa4a5af2 100644 --- a/api/include/SAM_TroughPhysical.h +++ b/api/include/SAM_TroughPhysical.h @@ -3655,6 +3655,8 @@ extern "C" SAM_EXPORT double* SAM_TroughPhysical_Outputs_rec_op_mode_final_aget(SAM_table ptr, int* length, SAM_error *err); + SAM_EXPORT double* SAM_TroughPhysical_Outputs_rec_time_in_startup_aget(SAM_table ptr, int* length, SAM_error *err); + SAM_EXPORT double* SAM_TroughPhysical_Outputs_recirculating_aget(SAM_table ptr, int* length, SAM_error *err); SAM_EXPORT double SAM_TroughPhysical_Outputs_required_number_of_loops_for_SM1_nget(SAM_table ptr, SAM_error *err); diff --git a/api/include/SAM_TroughPhysicalIph.h b/api/include/SAM_TroughPhysicalIph.h index 9cbcaf7db..784742c23 100644 --- a/api/include/SAM_TroughPhysicalIph.h +++ b/api/include/SAM_TroughPhysicalIph.h @@ -3519,6 +3519,8 @@ extern "C" SAM_EXPORT double* SAM_TroughPhysicalIph_Outputs_qinc_costh_aget(SAM_table ptr, int* length, SAM_error *err); + SAM_EXPORT double* SAM_TroughPhysicalIph_Outputs_rec_time_in_startup_aget(SAM_table ptr, int* length, SAM_error *err); + SAM_EXPORT double* SAM_TroughPhysicalIph_Outputs_recirculating_aget(SAM_table ptr, int* length, SAM_error *err); SAM_EXPORT double SAM_TroughPhysicalIph_Outputs_required_number_of_loops_for_SM1_nget(SAM_table ptr, SAM_error *err); diff --git a/api/modules/SAM_FresnelPhysical.cpp b/api/modules/SAM_FresnelPhysical.cpp index c06e4e326..be1c996ee 100644 --- a/api/modules/SAM_FresnelPhysical.cpp +++ b/api/modules/SAM_FresnelPhysical.cpp @@ -4953,6 +4953,16 @@ SAM_EXPORT double* SAM_FresnelPhysical_Outputs_rec_thermal_eff_aget(SAM_table pt return result; } +SAM_EXPORT double* SAM_FresnelPhysical_Outputs_rec_time_in_startup_aget(SAM_table ptr, int* length, SAM_error *err){ + double* result = nullptr; + translateExceptions(err, [&]{ + result = ssc_data_get_array(ptr, "rec_time_in_startup", length); + if (!result) + make_access_error("SAM_FresnelPhysical", "rec_time_in_startup"); + }); + return result; +} + SAM_EXPORT double* SAM_FresnelPhysical_Outputs_recirculating_aget(SAM_table ptr, int* length, SAM_error *err){ double* result = nullptr; translateExceptions(err, [&]{ diff --git a/api/modules/SAM_FresnelPhysicalIph.cpp b/api/modules/SAM_FresnelPhysicalIph.cpp index 14dcda4be..7dfcab117 100644 --- a/api/modules/SAM_FresnelPhysicalIph.cpp +++ b/api/modules/SAM_FresnelPhysicalIph.cpp @@ -5077,6 +5077,16 @@ SAM_EXPORT double* SAM_FresnelPhysicalIph_Outputs_rec_thermal_eff_aget(SAM_table return result; } +SAM_EXPORT double* SAM_FresnelPhysicalIph_Outputs_rec_time_in_startup_aget(SAM_table ptr, int* length, SAM_error *err){ + double* result = nullptr; + translateExceptions(err, [&]{ + result = ssc_data_get_array(ptr, "rec_time_in_startup", length); + if (!result) + make_access_error("SAM_FresnelPhysicalIph", "rec_time_in_startup"); + }); + return result; +} + SAM_EXPORT double* SAM_FresnelPhysicalIph_Outputs_recirculating_aget(SAM_table ptr, int* length, SAM_error *err){ double* result = nullptr; translateExceptions(err, [&]{ diff --git a/api/modules/SAM_TroughPhysical.cpp b/api/modules/SAM_TroughPhysical.cpp index 7e75226da..e2988d782 100644 --- a/api/modules/SAM_TroughPhysical.cpp +++ b/api/modules/SAM_TroughPhysical.cpp @@ -6898,6 +6898,16 @@ SAM_EXPORT double* SAM_TroughPhysical_Outputs_rec_op_mode_final_aget(SAM_table p return result; } +SAM_EXPORT double* SAM_TroughPhysical_Outputs_rec_time_in_startup_aget(SAM_table ptr, int* length, SAM_error *err){ + double* result = nullptr; + translateExceptions(err, [&]{ + result = ssc_data_get_array(ptr, "rec_time_in_startup", length); + if (!result) + make_access_error("SAM_TroughPhysical", "rec_time_in_startup"); + }); + return result; +} + SAM_EXPORT double* SAM_TroughPhysical_Outputs_recirculating_aget(SAM_table ptr, int* length, SAM_error *err){ double* result = nullptr; translateExceptions(err, [&]{ diff --git a/api/modules/SAM_TroughPhysicalIph.cpp b/api/modules/SAM_TroughPhysicalIph.cpp index a7effbe7b..f9eadb19c 100644 --- a/api/modules/SAM_TroughPhysicalIph.cpp +++ b/api/modules/SAM_TroughPhysicalIph.cpp @@ -6630,6 +6630,16 @@ SAM_EXPORT double* SAM_TroughPhysicalIph_Outputs_qinc_costh_aget(SAM_table ptr, return result; } +SAM_EXPORT double* SAM_TroughPhysicalIph_Outputs_rec_time_in_startup_aget(SAM_table ptr, int* length, SAM_error *err){ + double* result = nullptr; + translateExceptions(err, [&]{ + result = ssc_data_get_array(ptr, "rec_time_in_startup", length); + if (!result) + make_access_error("SAM_TroughPhysicalIph", "rec_time_in_startup"); + }); + return result; +} + SAM_EXPORT double* SAM_TroughPhysicalIph_Outputs_recirculating_aget(SAM_table ptr, int* length, SAM_error *err){ double* result = nullptr; translateExceptions(err, [&]{ diff --git a/src/casewin.cpp b/src/casewin.cpp index bba6634ce..8847dbe48 100644 --- a/src/casewin.cpp +++ b/src/casewin.cpp @@ -37,6 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include @@ -65,6 +66,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "macro.h" #include "../resource/graph.cpng" +#include "../resource/notes.cpng" + class CollapsePaneCtrl : public wxPanel { @@ -663,7 +666,8 @@ void CaseWindow::OnTree(wxDataViewEvent &evt) wxString title = m_navigationMenu->GetItemText(m_currentSelection); m_navigationMenu->SetFocus(); SwitchToInputPage(title); - + wxVariant x = wxDataViewIconText("text", wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); + m_navigationMenu->SetItemData(m_currentSelection,(wxClientData*) & x); } void CaseWindow::OnTreeCollapsing(wxDataViewEvent& evt) From f6b9f123be1c220d7a4cfd1ba071a33d3cd9eaa1 Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Mon, 7 Jul 2025 04:20:13 -0600 Subject: [PATCH 2/5] Working on notes icon - issue with InputPageList events not called #1552 --- src/casewin.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/casewin.cpp b/src/casewin.cpp index 8847dbe48..24ac98a51 100644 --- a/src/casewin.cpp +++ b/src/casewin.cpp @@ -663,11 +663,18 @@ void CaseWindow::OnTree(wxDataViewEvent &evt) else { m_currentSelection = evt.GetItem(); } + + if (HasPageNote(GetCurrentContext())) { + m_navigationMenu->SetItemIcon(m_currentSelection, wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); + //m_navigationMenu->im // TODO set images and override onImagesChanged method to show notes icon + m_navigationMenu->Refresh(); + } wxString title = m_navigationMenu->GetItemText(m_currentSelection); m_navigationMenu->SetFocus(); SwitchToInputPage(title); - wxVariant x = wxDataViewIconText("text", wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); - m_navigationMenu->SetItemData(m_currentSelection,(wxClientData*) & x); + +// wxVariant x = wxDataViewIconText("text", wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); +// m_navigationMenu->SetItemData(m_currentSelection,(wxClientData*) & x); } void CaseWindow::OnTreeCollapsing(wxDataViewEvent& evt) @@ -1080,7 +1087,7 @@ bool CaseWindow::SwitchToInputPage( const wxString &name ) wxBusyCursor wait; // m_inputPagePanel->Freeze(); - //DetachCurrentInputPage(); +// DetachCurrentInputPage(); m_currentGroup = 0; for( size_t i=0;iGetStringSelection() != name ) int p = m_inputPageList->Find(name); m_inputPageList->Select( p ); + m_inputPageList->Refresh(); return true; } From 4ecec2339f0bfb0cd97947d0a3659f3ed08633c6 Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Tue, 8 Jul 2025 04:00:02 -0600 Subject: [PATCH 3/5] Create notes icon on left side using updated wxMetroDataViewTreeCtrl --- src/casewin.cpp | 3 +++ src/ipagelist.cpp | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/casewin.cpp b/src/casewin.cpp index 24ac98a51..4466190fb 100644 --- a/src/casewin.cpp +++ b/src/casewin.cpp @@ -669,10 +669,12 @@ void CaseWindow::OnTree(wxDataViewEvent &evt) //m_navigationMenu->im // TODO set images and override onImagesChanged method to show notes icon m_navigationMenu->Refresh(); } + wxString title = m_navigationMenu->GetItemText(m_currentSelection); m_navigationMenu->SetFocus(); SwitchToInputPage(title); + m_left_panel->Layout(); // Issue 1552 // wxVariant x = wxDataViewIconText("text", wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); // m_navigationMenu->SetItemData(m_currentSelection,(wxClientData*) & x); } @@ -1112,6 +1114,7 @@ bool CaseWindow::SwitchToInputPage( const wxString &name ) int p = m_inputPageList->Find(name); m_inputPageList->Select( p ); m_inputPageList->Refresh(); + m_left_panel->Layout();// try to force onPaint call for the input page list return true; } diff --git a/src/ipagelist.cpp b/src/ipagelist.cpp index 6449aef7f..8920342b7 100644 --- a/src/ipagelist.cpp +++ b/src/ipagelist.cpp @@ -68,7 +68,7 @@ static wxColour SelectColour(204,204,204); static wxColour BackColour(243,243,243); InputPageList::InputPageList(wxWindow *parent, int id, const wxPoint &pos, const wxSize &size) - : wxScrolledWindow(parent,id, pos, size, wxBORDER_NONE) + : wxScrolledWindow(parent,id, pos, size, wxBORDER_NONE | wxFULL_REPAINT_ON_RESIZE) { SetBackgroundStyle(wxBG_STYLE_CUSTOM); SetBackgroundColour( BackColour ); @@ -273,8 +273,8 @@ void InputPageList::OnPaint(wxPaintEvent &) dc.SetBackground( wxBrush( GetBackgroundColour() ) ); - if (g_notesBitmap.IsOk() && m_caseWin - && m_caseWin->HasPageNote( m_items[i].resource ) ) +// if (g_notesBitmap.IsOk() && m_caseWin +// && m_caseWin->HasPageNote( m_items[i].resource ) ) { // int tx_w = dc.GetTextExtent( m_items[i].name ).GetWidth(); dc.DrawBitmap(g_notesBitmap, From 430bc7180b6dc5ab0b99a32a197daa4c95aa9045 Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Wed, 9 Jul 2025 04:39:27 -0600 Subject: [PATCH 4/5] Fix results issue in #1552 and make wxMetroDataViewTreeCtrl not editable --- src/casewin.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++++-- src/casewin.h | 1 + 2 files changed, 109 insertions(+), 4 deletions(-) diff --git a/src/casewin.cpp b/src/casewin.cpp index 4466190fb..2d4140a2e 100644 --- a/src/casewin.cpp +++ b/src/casewin.cpp @@ -640,6 +640,8 @@ bool CaseWindow::GenerateReport( wxString pdffile, wxString templfile, VarValue void CaseWindow::OnTree(wxDataViewEvent &evt) { + UpdateNotesIcon(); // when leaving a page and notes erased + m_pageFlipper->SetSelection(0); wxDataViewItem dvi = evt.GetItem(); if (!dvi.IsOk()) @@ -664,12 +666,22 @@ void CaseWindow::OnTree(wxDataViewEvent &evt) m_currentSelection = evt.GetItem(); } + /* if (HasPageNote(GetCurrentContext())) { m_navigationMenu->SetItemIcon(m_currentSelection, wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); //m_navigationMenu->im // TODO set images and override onImagesChanged method to show notes icon m_navigationMenu->Refresh(); } - + // update all navigation items note icon + m_navigationMenu->get + auto bmb = wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes)); + for (size_t i = 0; i < m_pageGroups.size(); i++) + if (HasPageNote(m_pageGroups[i]->HelpContext) + m_currentGroup = m_pageGroups[i]; + + */ + + wxString title = m_navigationMenu->GetItemText(m_currentSelection); m_navigationMenu->SetFocus(); SwitchToInputPage(title); @@ -1484,7 +1496,7 @@ void CaseWindow::UpdateConfiguration() if (cfg->TechnologyFullName.Contains("Generic")) return; //if generic get out of the loop wxDataViewItem dvi = m_navigationMenu->GetNthChild(wxDataViewItem(0), 0); - if (m_navigationMenu->IsContainer(dvi)) { + if (dvi.IsOk() && m_navigationMenu->IsContainer(dvi)) { dvi = m_navigationMenu->GetNthChild(dvi, 0); } @@ -1493,8 +1505,54 @@ void CaseWindow::UpdateConfiguration() m_currentSelection = (dvi); } + // update input page note icons -- TODO item + //m_navigationMenu->GetChildCount(wxDataViewItem(0)); + /* + #include + +// Assume 'myDVC' is your wxDataViewCtrl instance +// and it has an associated wxDataViewModel + +void IterateDataViewItems(wxDataViewCtrl* myDVC) +{ + wxDataViewModel* model = myDVC->GetModel(); + if (!model) + return; + + // Get the invisible root item (or the top-level items depending on your model) + wxDataViewItem root = model->GetParent(wxDataViewItem(nullptr)); // This might need adjustment depending on your model structure + + // Start iteration (depth-first traversal shown) + IterateChildren(myDVC, model, root); +} + +void IterateChildren(wxDataViewCtrl* myDVC, wxDataViewModel* model, const wxDataViewItem& parent) +{ + wxDataViewItemArray children; + model->GetChildren(parent, children); + + for (const wxDataViewItem& child : children) + { + // Do something with the child item + // For example, print its value in the first column + wxVariant value; + model->GetValue(value, child, 0); // Assuming column 0 + wxLogMessage("Item value: %s", value.GetString()); + + // Recursively iterate over its children if it's a container + if (model->IsContainer(child)) + { + IterateChildren(myDVC, model, child); + } + } +} + + + */ + + // check for orphaned notes and if any found add to first page per Github issue 796 - CheckAndUpdateNotes(inputPageHelpContext); +// CheckAndUpdateNotes(inputPageHelpContext); m_szsims->Clear(true); if (m_case->GetTechnology().Contains("wave") || m_case->GetTechnology().Contains("tidal")) { @@ -1592,16 +1650,62 @@ void CaseWindow::UpdatePageNote() // update ID m_lastPageNoteId = GetCurrentContext(); + // update text on page note wxString text = m_case->RetrieveNote( m_lastPageNoteId ); m_pageNote->SetText(text); - m_pageNote->Show( SamApp::Window()->GetCurrentCaseWindow() == this && !text.IsEmpty() ); + + bool bShowNote = SamApp::Window()->GetCurrentCaseWindow() == this && !text.IsEmpty(); + + m_pageNote->Show( bShowNote ); + + UpdateNotesIcon(); +} + +void CaseWindow::UpdateNotesIcon() +{ +// auto dvi = m_navigationMenu->GetCurrentItem(); + auto dvi = m_currentSelection; + bool bShowNote = false; + + if (dvi.IsOk()) { + + for (auto pg : m_pageGroups) { + if (pg->SideBarLabel == m_navigationMenu->GetItemText(dvi)) + bShowNote = HasPageNote(pg->HelpContext); + } + + wxString itemText = m_navigationMenu->GetItemText(dvi); + if (itemText == "Inputs" || itemText == "Results" || itemText == "Parametrics" || itemText == "Stochastic" || itemText == "P50 / P90" || itemText == "Macros" || itemText == "Uncertainty") { + m_pageNote->SetTitle("Notes for " + itemText); + } + else { + m_pageNote->SetTitle("Notes for " + m_lastPageNoteId); + } + if (bShowNote) { + auto bmb = wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes)); + m_navigationMenu->SetItemIcon(dvi, bmb); + } + else { + m_navigationMenu->SetItemIcon(dvi, wxNullBitmap); + } + m_navigationMenu->Refresh(); + } } void CaseWindow::ShowPageNote() { m_pageNote->Show(); m_pageNote->GetTextCtrl()->SetFocus(); + +// UpdateNotesIcon(true); +// set notes icon on the current item + auto dvi = m_navigationMenu->GetCurrentItem(); + if (dvi.IsOk()) { + m_navigationMenu->SetItemIcon(dvi, wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); + m_navigationMenu->Refresh(); + } +// UpdatePageNote(); } void CaseWindow::SetPageNote( const wxString ¬e ) diff --git a/src/casewin.h b/src/casewin.h index cb9b90375..f879846bc 100644 --- a/src/casewin.h +++ b/src/casewin.h @@ -87,6 +87,7 @@ class CaseWindow : public wxSplitterWindow, CaseEventListener wxString GetCurrentContext(); void UpdatePageNote(); + void UpdateNotesIcon(); void CheckAndUpdateNotes(const wxArrayString& inputPageHelpContext); bool HasPageNote( const wxString &id ); void ShowPageNote( ); From a70a1c5ddcf11026eece819c5405dd8954667dbd Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Fri, 11 Jul 2025 05:13:51 -0600 Subject: [PATCH 5/5] Address SAM issue #1552 along with wex pull request 188 https://github.com/NREL/wex/pull/188 --- src/casewin.cpp | 109 ++++++++++------------------------------- src/casewin.h | 3 +- src/main.cpp | 22 +++++++-- src/main.h | 2 + test_results_win64.csv | 8 +-- 5 files changed, 52 insertions(+), 92 deletions(-) diff --git a/src/casewin.cpp b/src/casewin.cpp index 2d4140a2e..7ec9f91eb 100644 --- a/src/casewin.cpp +++ b/src/casewin.cpp @@ -150,16 +150,11 @@ BEGIN_EVENT_TABLE( CaseWindow, wxSplitterWindow ) EVT_LISTBOX( ID_INPUTPAGELIST, CaseWindow::OnCommand ) EVT_DATAVIEW_SELECTION_CHANGED(ID_TechTree, CaseWindow::OnTree) EVT_DATAVIEW_ITEM_COLLAPSING(ID_TechTree, CaseWindow::OnTreeCollapsing) - -// EVT_DATAVIEW_ITEM_START_EDITING(ID_TechTree, CaseWindow::OnTreeActivated) -// EVT_DATAVIEW_ITEM_ACTIVATED(ID_TechTree, CaseWindow::OnTreeActivated) - //EVT_LISTBOX( ID_TechTree, CaseWindow::OnCommand) EVT_BUTTON( ID_EXCL_BUTTON, CaseWindow::OnCommand ) EVT_LISTBOX( ID_EXCL_RADIO, CaseWindow::OnCommand) EVT_CHECKBOX( ID_COLLAPSE, CaseWindow::OnCommand ) EVT_MENU_RANGE( ID_EXCL_OPTION, ID_EXCL_OPTION_MAX, CaseWindow::OnCommand ) EVT_LISTBOX( ID_EXCL_TABLIST, CaseWindow::OnCommand ) - EVT_NOTEBOOK_PAGE_CHANGED( ID_PAGES, CaseWindow::OnSubNotebookPageChanged ) EVT_NOTEBOOK_PAGE_CHANGED( ID_BASECASE_PAGES, CaseWindow::OnSubNotebookPageChanged ) END_EVENT_TABLE() @@ -180,7 +175,7 @@ CaseWindow::CaseWindow( wxWindow *parent, Case *c ) wxFont lafont(*wxNORMAL_FONT); lafont.SetWeight(wxFONTWEIGHT_BOLD); - m_pageNote = 0; + m_pageNote = new PageNote(this); // create page note before m_pageFlipper adds pages m_currentGroup = 0; // navigation menu objects @@ -300,8 +295,6 @@ CaseWindow::CaseWindow( wxWindow *parent, Case *c ) SetMinimumPaneSize( 50 ); SplitVertically( m_left_panel, m_pageFlipper, (int)(210*xScale) ); - m_pageNote = new PageNote( this ); - // load page note window geometry int nw_xrel, nw_yrel, nw_w, nw_h; double sf = wxGetScreenHDScale(); @@ -1505,52 +1498,6 @@ void CaseWindow::UpdateConfiguration() m_currentSelection = (dvi); } - // update input page note icons -- TODO item - //m_navigationMenu->GetChildCount(wxDataViewItem(0)); - /* - #include - -// Assume 'myDVC' is your wxDataViewCtrl instance -// and it has an associated wxDataViewModel - -void IterateDataViewItems(wxDataViewCtrl* myDVC) -{ - wxDataViewModel* model = myDVC->GetModel(); - if (!model) - return; - - // Get the invisible root item (or the top-level items depending on your model) - wxDataViewItem root = model->GetParent(wxDataViewItem(nullptr)); // This might need adjustment depending on your model structure - - // Start iteration (depth-first traversal shown) - IterateChildren(myDVC, model, root); -} - -void IterateChildren(wxDataViewCtrl* myDVC, wxDataViewModel* model, const wxDataViewItem& parent) -{ - wxDataViewItemArray children; - model->GetChildren(parent, children); - - for (const wxDataViewItem& child : children) - { - // Do something with the child item - // For example, print its value in the first column - wxVariant value; - model->GetValue(value, child, 0); // Assuming column 0 - wxLogMessage("Item value: %s", value.GetString()); - - // Recursively iterate over its children if it's a container - if (model->IsContainer(child)) - { - IterateChildren(myDVC, model, child); - } - } -} - - - */ - - // check for orphaned notes and if any found add to first page per Github issue 796 // CheckAndUpdateNotes(inputPageHelpContext); @@ -1650,8 +1597,7 @@ void CaseWindow::UpdatePageNote() // update ID m_lastPageNoteId = GetCurrentContext(); - - // update text on page note + // update text on page note wxString text = m_case->RetrieveNote( m_lastPageNoteId ); m_pageNote->SetText(text); @@ -1664,48 +1610,47 @@ void CaseWindow::UpdatePageNote() void CaseWindow::UpdateNotesIcon() { -// auto dvi = m_navigationMenu->GetCurrentItem(); - auto dvi = m_currentSelection; - bool bShowNote = false; + wxDataViewModel* model = m_navigationMenu->GetModel(); + if (!model) + return; - if (dvi.IsOk()) { + // Get the invisible root item + wxDataViewItem root = model->GetParent(wxDataViewItem(nullptr)); + + // Start iteration (depth-first traversal shown) + UpdateNotesIconChildren(model, root); +} +void CaseWindow::UpdateNotesIconChildren(wxDataViewModel* model, const wxDataViewItem& parent) +{ + wxDataViewItemArray children; + model->GetChildren(parent, children); + for (const wxDataViewItem& child : children) { + // Check if the child item has a note + bool bShowNote = false; for (auto pg : m_pageGroups) { - if (pg->SideBarLabel == m_navigationMenu->GetItemText(dvi)) + if (pg->SideBarLabel == m_navigationMenu->GetItemText(child)) bShowNote = HasPageNote(pg->HelpContext); } - wxString itemText = m_navigationMenu->GetItemText(dvi); - if (itemText == "Inputs" || itemText == "Results" || itemText == "Parametrics" || itemText == "Stochastic" || itemText == "P50 / P90" || itemText == "Macros" || itemText == "Uncertainty") { - m_pageNote->SetTitle("Notes for " + itemText); - } - else { - m_pageNote->SetTitle("Notes for " + m_lastPageNoteId); - } if (bShowNote) { - auto bmb = wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes)); - m_navigationMenu->SetItemIcon(dvi, bmb); + m_navigationMenu->SetItemIcon(child, wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); } else { - m_navigationMenu->SetItemIcon(dvi, wxNullBitmap); + m_navigationMenu->SetItemIcon(child, wxNullBitmap); + } + // Recursively check its children if it's a container + if (model->IsContainer(child)) { + UpdateNotesIconChildren(model, child); } - m_navigationMenu->Refresh(); } } + void CaseWindow::ShowPageNote() { m_pageNote->Show(); m_pageNote->GetTextCtrl()->SetFocus(); - -// UpdateNotesIcon(true); -// set notes icon on the current item - auto dvi = m_navigationMenu->GetCurrentItem(); - if (dvi.IsOk()) { - m_navigationMenu->SetItemIcon(dvi, wxBitmapBundle::FromBitmap(wxBITMAP_PNG_FROM_DATA(notes))); - m_navigationMenu->Refresh(); - } -// UpdatePageNote(); } void CaseWindow::SetPageNote( const wxString ¬e ) @@ -1719,7 +1664,7 @@ bool CaseWindow::HasPageNote(const wxString &id) return !id.IsEmpty() && !m_case->RetrieveNote(id).IsEmpty(); } -void CaseWindow::OnSubNotebookPageChanged( wxNotebookEvent & ) +void CaseWindow::OnSubNotebookPageChanged( wxNotebookEvent &evt ) { // common event handler for notebook page events to update the page note UpdatePageNote(); diff --git a/src/casewin.h b/src/casewin.h index f879846bc..19559750b 100644 --- a/src/casewin.h +++ b/src/casewin.h @@ -88,6 +88,8 @@ class CaseWindow : public wxSplitterWindow, CaseEventListener wxString GetCurrentContext(); void UpdatePageNote(); void UpdateNotesIcon(); + void UpdateNotesIconChildren(wxDataViewModel* model, const wxDataViewItem& parent); + //void IterateChildren(wxDataViewCtrl* myDVC, wxDataViewModel* model, const wxDataViewItem& parent) void CheckAndUpdateNotes(const wxArrayString& inputPageHelpContext); bool HasPageNote( const wxString &id ); void ShowPageNote( ); @@ -176,7 +178,6 @@ class CaseWindow : public wxSplitterWindow, CaseEventListener virtual void OnCaseEvent( Case *, CaseEvent & ); void OnSubNotebookPageChanged( wxNotebookEvent &evt ); - DECLARE_EVENT_TABLE(); }; diff --git a/src/main.cpp b/src/main.cpp index 8ab8a0f8d..902364d9c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -478,6 +478,8 @@ bool MainWindow::CreateNewCase( const wxString &_name, wxString tech, wxString f c->LoadDefaults(); m_project.AddCase(GetUniqueCaseName(_name), c); CreateCaseWindow( c ); + UpdateAllPageNotes(); + return true; } @@ -533,6 +535,11 @@ void MainWindow::DeleteCaseWindow( Case *c ) m_caseNotebook->DeletePage( m_caseNotebook->FindPage( cw ) ); m_caseTabList->Remove( m_project.GetCaseName( c ) ); m_caseTabList->Refresh(); + + if (m_caseTabList->Count() > 0) { + wxString case_name = m_caseTabList->GetLabel(0); + SwitchToCaseWindow(case_name); + } } extern void ShowIDEWindow(); @@ -1240,17 +1247,22 @@ bool MainWindow::SwitchToCaseWindow( const wxString &case_name ) } } - // update all the page notes so they get - // hidden/shown appropriately - for( size_t i=0;iGetPageCount();i++ ) - if ( CaseWindow *cw = dynamic_cast( m_caseNotebook->GetPage(i) ) ) - cw->UpdatePageNote(); + UpdateAllPageNotes(); return true; } else return false; } +void MainWindow::UpdateAllPageNotes() +{ + // update all the page notes so they get + // hidden/shown appropriately + for (size_t i = 0; iGetPageCount(); i++) + if (CaseWindow* cw = dynamic_cast(m_caseNotebook->GetPage(i))) + cw->UpdatePageNote(); +} + void MainWindow::OnCaseTabChange( wxCommandEvent &evt ) { int sel = evt.GetSelection(); diff --git a/src/main.h b/src/main.h index 7a21bb59c..df7e0967c 100644 --- a/src/main.h +++ b/src/main.h @@ -102,6 +102,8 @@ class MainWindow : public wxFrame void DeleteCaseWindow( Case *c ); bool SwitchToCaseWindow( const wxString &name ); + void UpdateAllPageNotes(); + bool LoadProject( const wxString &file ); bool SaveProject( const wxString &file ); diff --git a/test_results_win64.csv b/test_results_win64.csv index b28778021..6f7a71d5c 100644 --- a/test_results_win64.csv +++ b/test_results_win64.csv @@ -60,7 +60,7 @@ Standalone Battery,Merchant Plant,-6.8282e+06,28.139,NA,; Warning: IRR at end of Standalone Battery,Leveraged Partnership Flip,-6.8282e+06,75.8238,72.8932,; Warning: IRR at end of analysis period is not a number (NaN). This can indicate that revenues are too low to cover costs, or that they are excessively high compared to costs. Warning: IRR in target year is not a number (NaN). This can indicate that revenues are too low to cover costs, or that they are excessively high compared to costs. Warning: NPV is $-1.51094e+07. A negative NPV indicates project costs are higher than revenues. Standalone Battery,All Equity Partnership Flip,-6.8282e+06,80.0715,72.8932,; Warning: IRR at end of analysis period is not a number (NaN). This can indicate that revenues are too low to cover costs, or that they are excessively high compared to costs. Warning: IRR in target year is not a number (NaN). This can indicate that revenues are too low to cover costs, or that they are excessively high compared to costs. Warning: NPV is $-3.88136e+07. A negative NPV indicates project costs are higher than revenues. Standalone Battery,Sale Leaseback,-6.8282e+06,76.249,72.8932,; Warning: IRR at end of analysis period is not a number (NaN). This can indicate that revenues are too low to cover costs, or that they are excessively high compared to costs. Warning: NPV is $-1.98418e+07. A negative NPV indicates project costs are higher than revenues. Warning: NPV is $-8.19532e+07. A negative NPV indicates project costs are higher than revenues. -ETES,Single Owner,-466572896,15.0793,7.40746,; +ETES,Single Owner,-466572416,15.0793,7.40746,; PTES,Single Owner,-197595520,19.0302,10.3676,; Physical Trough,Single Owner,377430080,14.7263,14.5131,; Physical Trough,Merchant Plant,377430080,13.3388,NA,; @@ -105,9 +105,9 @@ Generic CSP System,All Equity Partnership Flip,592360448,12.8552,11.2639,; Warni Generic CSP System,Sale Leaseback,592360448,13.0371,11.2639,; Warning: NPV is $-1.04309e+08. A negative NPV indicates project costs are higher than revenues. Notice: time 0.00 { Generic solar model 2 }:\ The interpolation code must be 1 (interpolate) or 2 (nearest neighbor)The input value was 0, so it was reset to 1 Generic CSP System,LCOE Calculator,592360448,NA,NA,; Notice: time 0.00 { Generic solar model 2 }:\ The interpolation code must be 1 (interpolate) or 2 (nearest neighbor)The input value was 0, so it was reset to 1 Generic CSP System,None,592360448,NA,NA,; Notice: time 0.00 { Generic solar model 2 }:\ The interpolation code must be 1 (interpolate) or 2 (nearest neighbor)The input value was 0, so it was reset to 1 -MSPT IPH,None,1497517184,NA,NA,; -MSPT IPH,LCOH Calculator,1497517184,NA,NA,; -MSPT IPH,Single Owner,1550383232,6.2643,6.83681,; Notice: At time = 6087 CR_ON__PC_RM_HI__TES_FULL__AUX_OFF converged to a power cycle thermal input 278.765 [MWt] less than the target 279.126 [MWt]. +MSPT IPH,None,1497516928,NA,NA,; +MSPT IPH,LCOH Calculator,1497516928,NA,NA,; +MSPT IPH,Single Owner,1550383104,6.2643,6.83681,; Notice: At time = 6087 CR_ON__PC_RM_HI__TES_FULL__AUX_OFF converged to a power cycle thermal input 278.765 [MWt] less than the target 279.126 [MWt]. Physical Trough IPH,None,20907466,NA,NA,; Physical Trough IPH,LCOH Calculator,20907466,NA,NA,; Physical Trough IPH,Single Owner,20907466,7.5501,7.02159,;