Commit f28c7d04 authored by Stefan Pfeifer's avatar Stefan Pfeifer

Add a status bar to the main window for input validation errors

parent 03ab9076
Pipeline #41801855 passed with stage
in 9 minutes and 42 seconds
......@@ -34,55 +34,45 @@ OutputData BowModel::run_dynamic_simulation(const InputData& input, const Callba
return model.output;
}
BowModel::BowModel(const InputData& input, const Callback& callback)
: input(input)
{
check_input(input);
init_limb(callback);
init_string(callback);
init_masses(callback);
}
void BowModel::check_input(const InputData& input)
boost::optional<std::string> BowModel::validate_input(const InputData& input)
{
// Check Settings
if(input.settings.n_limb_elements < 1)
throw std::runtime_error("Settings: Number of limb elements must be positive");
return std::string("Settings: Number of limb elements must be positive");
if(input.settings.n_string_elements < 1)
throw std::runtime_error("Settings: Number of string elements must be positive");
return std::string("Settings: Number of string elements must be positive");
if(input.settings.n_draw_steps < 1)
throw std::runtime_error("Settings: Number of draw steps must be positive");
return std::string("Settings: Number of draw steps must be positive");
if(input.settings.time_span_factor <= 0.0)
throw std::runtime_error("Settings: Time span factor must be positive");
return std::string("Settings: Time span factor must be positive");
if(input.settings.time_step_factor <= 0.0)
throw std::runtime_error("Settings: Time step factor must be positive");
return std::string("Settings: Time step factor must be positive");
if(input.settings.sampling_rate <= 0.0)
throw std::runtime_error("Settings: Sampling rate must be positive");
return std::string("Settings: Sampling rate must be positive");
// Check Profile
for(double arg: input.profile.args())
{
if(arg <= 0.0)
throw std::runtime_error("Profile: Segment lengths must be positive");
return std::string("Profile: Segment lengths must be positive");
}
// Check width
if(input.width.size() < 2)
throw std::runtime_error("Width: At least two data points are needed");
return std::string("Width: At least two data points are needed");
for(double w: input.width.vals())
{
if(w <= 0.0)
throw std::runtime_error("Width must be positive");
return std::string("Width must be positive");
}
// Check Layers
......@@ -92,50 +82,62 @@ void BowModel::check_input(const InputData& input)
const Layer& layer = input.layers[i];
if(layer.rho <= 0.0)
throw std::runtime_error("Layer " + std::to_string(i) + " (" + layer.name + ")" + ": rho must be positive");
return "Layer " + std::to_string(i) + " (" + layer.name + ")" + ": rho must be positive";
if(layer.E <= 0.0)
throw std::runtime_error("Layer " + std::to_string(i) + " (" + layer.name + ")" + ": E must be positive");
return "Layer " + std::to_string(i) + " (" + layer.name + ")" + ": E must be positive";
if(layer.height.size() < 2)
throw std::runtime_error("Layer " + std::to_string(i) + " (" + layer.name + ")" + ": At least two data points for height are needed");
return "Layer " + std::to_string(i) + " (" + layer.name + ")" + ": At least two data points for height are needed";
for(double h: layer.height.vals())
{
if(h <= 0.0)
throw std::runtime_error("Layer " + std::to_string(i) + " (" + layer.name + ")" + ": Height must be positive");
return "Layer " + std::to_string(i) + " (" + layer.name + ")" + ": Height must be positive";
}
}
// Check String
if(input.string.strand_stiffness <= 0.0)
throw std::runtime_error("String: Strand stiffness must be positive");
return std::string("String: Strand stiffness must be positive");
if(input.string.strand_density <= 0.0)
throw std::runtime_error("String: Strand density must be positive");
return std::string("String: Strand density must be positive");
if(input.string.n_strands < 1)
throw std::runtime_error("String: Number of strands must be positive");
return std::string("String: Number of strands must be positive");
// Check Masses
if(input.masses.string_center < 0.0)
throw std::runtime_error("Masses: String center mass must not be negative");
return std::string("Masses: String center mass must not be negative");
if(input.masses.string_tip < 0.0)
throw std::runtime_error("Masses: String tip mass must not be negative");
return std::string("Masses: String tip mass must not be negative");
if(input.masses.limb_tip < 0.0)
throw std::runtime_error("Masses: Limb tip mass must not be negative");
return std::string("Masses: Limb tip mass must not be negative");
// Check Operation
if(input.dimensions.brace_height >= input.dimensions.draw_length)
throw std::runtime_error("Operation: Draw length must be greater than brace height");
return std::string("Operation: Draw length must be greater than brace height");
if(input.masses.arrow <= 0.0)
throw std::runtime_error("Operation: Arrow mass must be positive");
return std::string("Operation: Arrow mass must be positive");
return boost::none;
}
BowModel::BowModel(const InputData& input, const Callback& callback)
: input(input)
{
assert(validate_input(input) == boost::none);
init_limb(callback);
init_string(callback);
init_masses(callback);
}
void BowModel::init_limb(const Callback& callback)
......
......@@ -2,6 +2,7 @@
#include "bow/input/InputData.hpp"
#include "bow/output/OutputData.hpp"
#include "fem/System.hpp"
#include <boost/optional.hpp>
#include <functional>
class BowModel
......@@ -10,11 +11,11 @@ public:
using Callback = std::function<bool(int)>; // Progress (percent) -> Continue (true/false)
static OutputData run_static_simulation(const InputData& input, const Callback& callback);
static OutputData run_dynamic_simulation(const InputData& input, const Callback& callback1, const Callback& callback2);
static boost::optional<std::string> validate_input(const InputData& input);
private:
BowModel(const InputData& input, const Callback& callback);
void check_input(const InputData& input);
void init_limb(const Callback& callback);
void init_string(const Callback& callback);
void init_masses(const Callback& callback);
......
......@@ -85,6 +85,7 @@ MainWindow::MainWindow()
// Main window
this->setWindowIcon(QIcon(":/icons/logo"));
this->statusBar()->setStyleSheet("color: red");
this->setCentralWidget(editor);
setCurrentFile(QString());
......@@ -93,8 +94,22 @@ MainWindow::MainWindow()
restoreGeometry(Application::settings.value("MainWindow/geometry").toByteArray());
// Set Window's modification indicator when data has changed
QObject::connect(editor, &BowEditor::modified, [&]{
QObject::connect(editor, &BowEditor::modified, [&, action_run_statics, action_run_dynamics]{
InputData new_data = editor->getData();
auto error = BowModel::validate_input(new_data);
if(error)
{
action_run_statics->setEnabled(false);
action_run_dynamics->setEnabled(false);
this->statusBar()->showMessage(QString::fromStdString(*error));
}
else
{
action_run_statics->setEnabled(true);
action_run_dynamics->setEnabled(true);
this->statusBar()->clearMessage();
}
this->setWindowModified(new_data != data);
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment