@@ -157,7 +157,7 @@ void App::LoadSettings()
157157#else
158158 settings.hide_spoilers = false ;
159159#endif
160- settings.hide_somersloop = json.contains (" hide_somersloop" ) && json[" hide_somersloop" ].get <bool >(); // default true
160+ settings.hide_somersloop = json.contains (" hide_somersloop" ) && json[" hide_somersloop" ].get <bool >(); // default false
161161 settings.unlocked_alts = {};
162162
163163 for (const auto & r : Data::Recipes ())
@@ -168,6 +168,8 @@ void App::LoadSettings()
168168 }
169169 }
170170
171+ settings.hide_build_progress = !json.contains (" hide_build_progress" ) || json[" hide_build_progress" ].get <bool >(); // default true
172+
171173 if (!content.has_value ())
172174 {
173175 SaveSettings ();
@@ -190,6 +192,8 @@ void App::SaveSettings() const
190192 }
191193 serialized[" unlocked_alts" ] = unlocked;
192194
195+ serialized[" hide_build_progress" ] = settings.hide_build_progress ;
196+
193197 SaveFile (settings_file.data (), serialized.Dump ());
194198}
195199
@@ -1259,6 +1263,7 @@ void App::Render()
12591263 ax::NodeEditor::SetCurrentEditor (context);
12601264 ax::NodeEditor::PushStyleColor (ax::NodeEditor::StyleColor_Flow, ImColor (1 .0f , 1 .0f , 0 .0f ));
12611265 ax::NodeEditor::PushStyleColor (ax::NodeEditor::StyleColor_FlowMarker, ImColor (1 .0f , 1 .0f , 0 .0f ));
1266+ ax::NodeEditor::PushStyleVar (ax::NodeEditor::StyleVar_SelectedNodeBorderWidth, 5 .0f );
12621267
12631268 ImGui::BeginChild (" #left_panel" , ImVec2 (0 .2f * ImGui::GetWindowSize ().x , 0 .0f ), false , ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NoNavInputs);
12641269 RenderLeftPanel ();
@@ -1297,6 +1302,7 @@ void App::Render()
12971302 CustomKeyControl ();
12981303
12991304 ax::NodeEditor::End ();
1305+ ax::NodeEditor::PopStyleVar ();
13001306 ax::NodeEditor::PopStyleColor ();
13011307 ax::NodeEditor::PopStyleColor ();
13021308
@@ -1578,6 +1584,33 @@ void App::RenderLeftPanel()
15781584 " If set, the power per node will be calculated assuming all machines are set at the same clock value\n "
15791585 " Otherwise, it will be calculated with machines at 100% and one last machine underclocked" );
15801586 }
1587+ if (ImGui::Checkbox (" Hide build progress" , &settings.hide_build_progress ))
1588+ {
1589+ SaveSettings ();
1590+ }
1591+ if (ImGui::IsItemHovered (ImGuiHoveredFlags_AllowWhenDisabled))
1592+ {
1593+ ImGui::SetTooltip (" %s" , " If set, build checkmark on craft nodes and overall progress bars won't be displayed" );
1594+ }
1595+ if (!settings.hide_build_progress )
1596+ {
1597+ ImGui::SameLine ();
1598+ if (ImGui::Button (" Reset progress" ))
1599+ {
1600+ for (auto & n : nodes)
1601+ {
1602+ if (n->IsCraft ())
1603+ {
1604+ static_cast <CraftNode*>(n.get ())->built = false ;
1605+ }
1606+ else if (n->IsGroup ())
1607+ {
1608+ static_cast <GroupNode*>(n.get ())->SetBuiltState (false );
1609+ }
1610+ }
1611+ }
1612+ }
1613+
15811614
15821615 if (ImGui::Button (" Unlock all alt recipes" ))
15831616 {
@@ -1612,6 +1645,9 @@ void App::RenderLeftPanel()
16121645 std::map<const Item*, FractionalNumber, ItemPtrCompare> outputs;
16131646 std::map<const Item*, FractionalNumber, ItemPtrCompare> intermediates;
16141647 std::map<std::string, FractionalNumber> total_machines;
1648+ FractionalNumber all_machines;
1649+ std::map<std::string, FractionalNumber> built_machines;
1650+ FractionalNumber all_built_machines;
16151651 std::map<std::string, std::map<const Recipe*, FractionalNumber, RecipePtrCompare>> detailed_machines;
16161652 FractionalNumber total_sink_points;
16171653 std::map<const Item*, FractionalNumber> detailed_sink_points;
@@ -1635,7 +1671,10 @@ void App::RenderLeftPanel()
16351671
16361672 const CraftNode* node = static_cast <const CraftNode*>(n.get ());
16371673 total_machines[node->recipe ->building ->name ] += node->current_rate ;
1674+ all_machines += node->current_rate ;
16381675 detailed_machines[node->recipe ->building ->name ][node->recipe ] += node->current_rate ;
1676+ built_machines[node->recipe ->building ->name ] += node->built ? node->current_rate : 0 ;
1677+ all_built_machines += node->built ? node->current_rate : 0 ;
16391678 total_power += settings.power_equal_clocks ? node->same_clock_power : node->last_underclock_power ;
16401679 detailed_power[node->recipe ] += settings.power_equal_clocks ? node->same_clock_power : node->last_underclock_power ;
16411680 has_variable_power |= node->recipe ->building ->variable_power ;
@@ -1658,6 +1697,12 @@ void App::RenderLeftPanel()
16581697 for (const auto & [k, v] : node->total_machines )
16591698 {
16601699 total_machines[k] += v;
1700+ all_machines += v;
1701+ }
1702+ for (const auto & [k, v] : node->built_machines )
1703+ {
1704+ built_machines[k] += v;
1705+ all_built_machines += v;
16611706 }
16621707 for (const auto & [k, v] : node->detailed_machines )
16631708 {
@@ -1700,6 +1745,46 @@ void App::RenderLeftPanel()
17001745 }
17011746 }
17021747
1748+ if (!settings.hide_build_progress )
1749+ {
1750+ ImGui::SeparatorText (" Build Progress" );
1751+
1752+ // Progress bar color
1753+ ImGui::PushStyleColor (ImGuiCol_::ImGuiCol_PlotHistogram, ImVec4 (0 , 0.5 , 0 , 1 ));
1754+ // No visible color change when hovered/click
1755+ ImGui::PushStyleColor (ImGuiCol_::ImGuiCol_HeaderHovered, ImVec4 (0 , 0 , 0 , 0 ));
1756+ ImGui::PushStyleColor (ImGuiCol_::ImGuiCol_HeaderActive, ImVec4 (0 , 0 , 0 , 0 ));
1757+ const bool display_build_details = ImGui::TreeNodeEx (" ##build_progress" , ImGuiTreeNodeFlags_FramePadding | ImGuiTreeNodeFlags_SpanAvailWidth);
1758+ ImGui::PopStyleColor ();
1759+ ImGui::PopStyleColor ();
1760+
1761+ // Displayed over the TreeNodeEx element (same line)
1762+ ImGui::SameLine ();
1763+ ImGui::ProgressBar (all_machines.GetNumerator () == 0 ? 0 .0f : static_cast <float >((all_built_machines / all_machines).GetValue ()));
1764+ float max_machine_name_width = 0 .0f ;
1765+ for (auto & [machine, f] : built_machines)
1766+ {
1767+ max_machine_name_width = std::max (max_machine_name_width, ImGui::CalcTextSize (machine.c_str ()).x );
1768+ }
1769+ // Detailed list of recipes if the tree node is open
1770+ if (display_build_details)
1771+ {
1772+ ImGui::Indent ();
1773+ for (auto & [machine, f] : built_machines)
1774+ {
1775+ ImGui::TextUnformatted (machine.c_str ());
1776+ ImGui::SameLine ();
1777+ ImGui::Dummy (ImVec2 (max_machine_name_width - ImGui::CalcTextSize (machine.c_str ()).x , 0 .0f ));
1778+ ImGui::SameLine ();
1779+ ImGui::ProgressBar ((f / total_machines[machine]).GetValue ());
1780+ }
1781+
1782+ ImGui::Unindent ();
1783+ ImGui::TreePop ();
1784+ }
1785+ ImGui::PopStyleColor ();
1786+ }
1787+
17031788 ImGui::SeparatorText (has_variable_power ? " Average Power Consumption" : " Power Consumption" );
17041789 if (total_power.GetNumerator () != 0 )
17051790 {
@@ -1996,6 +2081,14 @@ void App::RenderNodes()
19962081 ax::NodeEditor::PushStyleColor (ax::NodeEditor::StyleColor_NodeBorder, ImColor (255 , 0 , 0 ));
19972082 node_pushed_style += 1 ;
19982083 }
2084+ if (!settings.hide_build_progress && (
2085+ (node->IsCraft () && static_cast <CraftNode*>(node.get ())->built ) ||
2086+ (node->IsGroup () && static_cast <GroupNode*>(node.get ())->built_machines == static_cast <GroupNode*>(node.get ())->total_machines )
2087+ ))
2088+ {
2089+ ax::NodeEditor::PushStyleColor (ax::NodeEditor::StyleColor_NodeBorder, ImColor (0 , 255 , 0 ));
2090+ node_pushed_style += 1 ;
2091+ }
19992092 ax::NodeEditor::BeginNode (node->id );
20002093 ImGui::PushID (node->id .AsPointer ());
20012094 ImGui::BeginVertical (" node" );
@@ -2005,7 +2098,18 @@ void App::RenderNodes()
20052098 switch (node->GetKind ())
20062099 {
20072100 case Node::Kind::Craft:
2008- ImGui::TextUnformatted (static_cast <CraftNode*>(node.get ())->recipe ->display_name .c_str ());
2101+ {
2102+ CraftNode* craft_node = static_cast <CraftNode*>(node.get ());
2103+ ImGui::Spring (1 .0f );
2104+ ImGui::TextUnformatted (craft_node->recipe ->display_name .c_str ());
2105+ ImGui::Spring (1 .0f );
2106+ if (!settings.hide_build_progress )
2107+ {
2108+ ImGui::PushStyleVar (ImGuiStyleVar_::ImGuiStyleVar_FramePadding, ImVec2 (0 , 0 ));
2109+ ImGui::Checkbox (" ##craft_built" , &craft_node->built );
2110+ ImGui::PopStyleVar ();
2111+ }
2112+ }
20092113 break ;
20102114 case Node::Kind::Merger:
20112115 ImGui::TextUnformatted (" Merger" );
@@ -2021,11 +2125,23 @@ void App::RenderNodes()
20212125 break ;
20222126 case Node::Kind::Group:
20232127 {
2128+ GroupNode* group_node = static_cast <GroupNode*>(node.get ());
2129+ ImGui::Spring (1 .0f );
20242130 ImGui::TextUnformatted (" Group" );
20252131 ImGui::Spring (0 .0f );
2026- std::string& name = static_cast <GroupNode*>(node.get ())->name ;
2027- ImGui::SetNextItemWidth (std::max (ImGui::CalcTextSize (name.c_str ()).x , ImGui::CalcTextSize (" Name..." ).x ) + ImGui::GetStyle ().FramePadding .x * 4 .0f );
2028- ImGui::InputTextWithHint (" ##name" , " Name..." , &name);
2132+ ImGui::SetNextItemWidth (std::max (ImGui::CalcTextSize (group_node->name .c_str ()).x , ImGui::CalcTextSize (" Name..." ).x ) + ImGui::GetStyle ().FramePadding .x * 4 .0f );
2133+ ImGui::InputTextWithHint (" ##name" , " Name..." , &group_node->name );
2134+ ImGui::Spring (1 .0f );
2135+ if (!settings.hide_build_progress )
2136+ {
2137+ ImGui::PushStyleVar (ImGuiStyleVar_::ImGuiStyleVar_FramePadding, ImVec2 (0 , 0 ));
2138+ bool is_built = group_node->built_machines == group_node->total_machines ;
2139+ if (ImGui::Checkbox (" ##group_built" , &is_built))
2140+ {
2141+ group_node->SetBuiltState (is_built);
2142+ }
2143+ ImGui::PopStyleVar ();
2144+ }
20292145 break ;
20302146 }
20312147 }
0 commit comments