@@ -110,6 +110,55 @@ void PreferenceDialog::FindFontFiles(const string& path)
110110// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
111111// Rendering
112112
113+ bool PreferenceDialog::DefaultButton (const std::string& label, const std::string& id, bool centered)
114+ {
115+ float buttonWidth = ImGui::CalcTextSize (label.c_str ()).x + ImGui::GetStyle ().FramePadding .x * 2 .0f ;
116+ float availWidth = ImGui::GetContentRegionAvail ().x ;
117+ float cursorX = ImGui::GetCursorPosX ();
118+ float xPos = centered ? (cursorX + (availWidth - buttonWidth)/2 .0f ) : (cursorX + availWidth - buttonWidth);
119+ ImGui::SetCursorPosX (xPos);
120+ ImGui::PushID (id.c_str ());
121+ bool result = ImGui::Button (label.c_str ());
122+ ImGui::PopID ();
123+ ImGui::SameLine (cursorX);
124+ return result;
125+ }
126+
127+ void PreferenceDialog::OpenConfirmDialog (const std::string& title, const std::string& message, const std::string& identifier)
128+ {
129+ ImGui::OpenPopup ((title + " ###" + identifier).c_str ());
130+ m_confirmDialogTitle = title;
131+ m_confirmDialogMessage = message;
132+ }
133+
134+ bool PreferenceDialog::RenderConfirmDialog (const std::string& identifier)
135+ {
136+ bool confirmed = false ;
137+ if (ImGui::BeginPopupModal ((m_confirmDialogTitle + " ###" + identifier).c_str (), nullptr ,ImGuiWindowFlags_AlwaysAutoResize))
138+ {
139+ ImGui::TextWrapped (" %s" , m_confirmDialogMessage.c_str ());
140+ ImGui::Separator ();
141+ float buttonWidth = ImGui::GetFontSize ()*6 ;
142+ // OK button
143+ if (ImGui::Button (" OK" , ImVec2 (buttonWidth, 0 )))
144+ {
145+ confirmed = true ;
146+ ImGui::CloseCurrentPopup ();
147+ }
148+ ImGui::SameLine ();
149+ // Cancel button
150+ if (ImGui::Button (" Cancel" , ImVec2 (buttonWidth, 0 )) || ImGui::IsKeyPressed (ImGuiKey_Escape))
151+ {
152+ ImGui::CloseCurrentPopup ();
153+ }
154+ // Default focus on cancel buttun
155+ ImGui::SetItemDefaultFocus ();
156+ ImGui::EndPopup ();
157+ }
158+ return confirmed;
159+ }
160+
161+
113162/* *
114163 @brief Renders the dialog and handles UI events
115164
@@ -132,13 +181,39 @@ bool PreferenceDialog::DoRender()
132181 if (subCategory.IsVisible ())
133182 {
134183 ImGui::PushID (identifier.c_str ());
184+ if (DefaultButton (" Default section" ,identifier))
185+ {
186+ OpenConfirmDialog (" Reset to default" ," Reset all settings in this section to default?" ,identifier);
187+ }
188+ if (RenderConfirmDialog (identifier))
189+ {
190+ ResetCategoryToDefault (subCategory);
191+ }
135192 if (ImGui::CollapsingHeader (identifier.c_str ()))
136193 ProcessCategory (subCategory);
137194 ImGui::PopID ();
138195 }
139196 }
140197 }
141198
199+ ImGui::NewLine ();
200+ if (DefaultButton (" Default all Preferences" ," ###resetAll" ,true ))
201+ {
202+ OpenConfirmDialog (" Reset to default" ," Reset all settings to default?" ," resetAll" );
203+ }
204+ if (RenderConfirmDialog (" resetAll" ))
205+ {
206+ for (const auto & identifier: root.GetOrdering ())
207+ {
208+ auto & node = children[identifier];
209+
210+ if (node->IsCategory ())
211+ {
212+ auto & subCategory = node->AsCategory ();
213+ ResetCategoryToDefault (subCategory);
214+ }
215+ }
216+ }
142217 return true ;
143218}
144219
@@ -159,6 +234,14 @@ void PreferenceDialog::ProcessCategory(PreferenceCategory& cat)
159234
160235 if (subCategory.IsVisible ())
161236 {
237+ if (DefaultButton (" Default category" ,identifier))
238+ {
239+ OpenConfirmDialog (" Reset to default" ," Reset all settings in this category to default?" ,identifier);
240+ }
241+ if (RenderConfirmDialog (identifier))
242+ {
243+ ResetCategoryToDefault (subCategory);
244+ }
162245 if (ImGui::TreeNode (identifier.c_str ()))
163246 {
164247 ImGui::PushID (identifier.c_str ());
@@ -175,6 +258,34 @@ void PreferenceDialog::ProcessCategory(PreferenceCategory& cat)
175258 }
176259}
177260
261+ /* *
262+ @brief Reset all preferences in this category to default
263+ */
264+ void PreferenceDialog::ResetCategoryToDefault (PreferenceCategory& cat)
265+ {
266+ auto & children = cat.GetChildren ();
267+ for (const auto & identifier: cat.GetOrdering ())
268+ {
269+ auto & node = children[identifier];
270+
271+ // Add child categories
272+ if (node->IsCategory ())
273+ {
274+ auto & subCategory = node->AsCategory ();
275+ ResetCategoryToDefault (subCategory);
276+ }
277+
278+ // Add preference widgets
279+ if (node->IsPreference ())
280+ {
281+ auto & pref = node->AsPreference ();
282+ pref.ResetToDefault ();
283+ // Clear cache
284+ m_preferenceTemporaries.erase (pref.GetIdentifier ());
285+ }
286+ }
287+ }
288+
178289/* *
179290 @brief Run the UI for a single preference
180291 */
@@ -328,4 +439,12 @@ void PreferenceDialog::ProcessPreference(Preference& pref)
328439 }
329440
330441 HelpMarker (pref.GetDescription ());
442+ label = " Default###" + pref.GetIdentifier () + " default" ;
443+ ImGui::SameLine ();
444+ if (ImGui::Button (label.c_str ()))
445+ {
446+ pref.ResetToDefault ();
447+ // Clear cache
448+ m_preferenceTemporaries.erase (pref.GetIdentifier ());
449+ }
331450}
0 commit comments