Skip to content
Snippets Groups Projects
Commit 7747f99e authored by tobiglaser's avatar tobiglaser
Browse files

added Doxxygen comments

parent da6392dd
No related branches found
No related tags found
No related merge requests found
......@@ -10,11 +10,16 @@
namespace cute
{
struct Point
struct Point ///< Representation of a Point in 2D-Space used by this library.
{
float x;
float y;
};
/**
* @brief This enum can be used to set different levels of detail in your plotting.
* They are in ascending order, so you can do if(verbosity() >= result).
*/
enum Verbosity
{
silent,
......@@ -23,11 +28,19 @@ namespace cute
verbose,
all
};
enum Scale
enum Scale ///< Representing different axis scalings.
{
linear,
logarithmic
};
/**
* @brief Representation of RGB colors used when drawing points and lines.
* For the Transparency, 0 is fully visible, 255 is unvisible.
* Think of it as the inverse of the alpha in RGBA.all
* @todo This should just be Alpha, shouldn't it?
*/
struct Color
{
uint8_t red;
......@@ -35,7 +48,8 @@ namespace cute
uint8_t blue;
uint8_t transparency;
};
enum LineStyle
enum LineStyle ///< Different possibilities to draw your lines.
{
none,
solid,
......@@ -44,41 +58,44 @@ namespace cute
dashDot,
DashDotDot
};
enum Shape
enum Shape ///< Draw your Points as circles or rectangles.
{
circle,
rectangle
};
namespace Colors
namespace Colors ///< A collection of Color presets. Not exhaustive, try them, change them, suggest other ones.
{
constexpr Color none = {0, 0, 0, 0xFF};
constexpr Color white = {0xFF, 0xFF, 0xFF, 0};
constexpr Color black = {0, 0, 0, 0};
constexpr Color red = {0xFF, 0, 0, 0};
constexpr Color darkRed = {0x80, 0, 0, 0};
constexpr Color green = {0, 0xFF, 0, 0};
constexpr Color darkGreen = {0, 0x80, 0, 0};
constexpr Color blue = {0, 0, 0xFF, 0};
constexpr Color darkBlue = {0, 0, 0x80, 0};
constexpr Color cyan = {0, 0xFF, 0xFF, 0};
constexpr Color darkCyan = {0, 0x80, 0x80, 0};
constexpr Color magenta = {0xFF, 0, 0xFF, 0};
constexpr Color darkMagenta = {0x80, 0, 0x80, 0};
constexpr Color yellow = {0xFF, 0xFF, 0, 0};
constexpr Color darkYellow = {0x80, 0x80, 0, 0};
constexpr Color gray = {0xA0, 0xA0, 0xA4, 0};
constexpr Color darkGray = {0x80, 0x80, 0x80, 0};
constexpr Color lightGray = {0xC0, 0xC0, 0xC0, 0};
constexpr Color none = {0, 0, 0, 0xFF}; ///< {0, 0, 0, 0xFF}
constexpr Color white = {0xFF, 0xFF, 0xFF, 0}; ///< {0xFF, 0xFF, 0xFF, 0}
constexpr Color black = {0, 0, 0, 0}; ///< {0, 0, 0, 0}
constexpr Color red = {0xFF, 0, 0, 0}; ///< {0xFF, 0, 0, 0}
constexpr Color darkRed = {0x80, 0, 0, 0}; ///< {0x80, 0, 0, 0}
constexpr Color green = {0, 0xFF, 0, 0}; ///< {0, 0xFF, 0, 0}
constexpr Color darkGreen = {0, 0x80, 0, 0}; ///< {0, 0x80, 0, 0}
constexpr Color blue = {0, 0, 0xFF, 0}; ///< {0, 0, 0xFF, 0}
constexpr Color darkBlue = {0, 0, 0x80, 0}; ///< {0, 0, 0x80, 0}
constexpr Color cyan = {0, 0xFF, 0xFF, 0}; ///< {0, 0xFF, 0xFF, 0}
constexpr Color darkCyan = {0, 0x80, 0x80, 0}; ///< {0, 0x80, 0x80, 0}
constexpr Color magenta = {0xFF, 0, 0xFF, 0}; ///< {0xFF, 0, 0xFF, 0}
constexpr Color darkMagenta = {0x80, 0, 0x80, 0}; ///< {0x80, 0, 0x80, 0}
constexpr Color yellow = {0xFF, 0xFF, 0, 0}; ///< {0xFF, 0xFF, 0, 0}
constexpr Color darkYellow = {0x80, 0x80, 0, 0}; ///< {0x80, 0x80, 0, 0}
constexpr Color gray = {0xA0, 0xA0, 0xA4, 0}; ///< {0xA0, 0xA0, 0xA4, 0}
constexpr Color darkGray = {0x80, 0x80, 0x80, 0}; ///< {0x80, 0x80, 0x80, 0}
constexpr Color lightGray = {0xC0, 0xC0, 0xC0, 0}; ///< {0xC0, 0xC0, 0xC0, 0}
} // namespace Colors
struct PlotProperties
struct PlotProperties ///< A structure to bundle all the possibilities to infuelce how your Data should be plotted.
{
std::string name = "";
int size = 10;
Color color = Colors::none;
LineStyle line = solid;
bool onTop = false;
bool legend = true;
Shape shape = circle;
std::string name = ""; ///< The name displayed in the Legend. An empty name will cause it not to be displayed.
int size = 10; ///< The diameter of points and the width of lines. No fix unit sadly, adjust yourself.
Color color = Colors::none; ///< The color of what you want plotted. The default value none will have a color chosen at random.
LineStyle line = solid; ///< The style, you want lines to be drawn in.
bool onTop = false; ///< Wether that Data should always be displayed above other data. So you dont have to redraw points manually all the time.
bool legend = true; ///< Whether you want the data to show up in the legend.
Shape shape = circle; ///< The shape you want points to have.
};
void DYNAMIC setPlotVisible(int plot, bool visible = true);
void DYNAMIC setPlotTitle(int plot, const std::string& title);
......@@ -132,15 +149,19 @@ namespace cute
std::chrono::microseconds DYNAMIC timerResult();
/**
* @brief This is only here to facilitate loading and unloading functions, loaded dynamically from a .dll.
* @todo With the current approach or with static libraries, this is unneccessary.
*/
namespace core
{
// These are for loading and unloading libcute.dll at runtime
#if !defined(RUNTIME_LOAD) and !defined(EXPORT_CUTE)
inline int initialize()
inline int initialize() ///< In case of not loading at runtime and importing cute as the User, do nothing.
{
return 0;
}
inline void shutdown() {}
inline void shutdown() {} ///< In case of not loading at runtime and importing cute as the User, do nothing.
#else
int initialize();
void shutdown();
......
......@@ -21,7 +21,10 @@
#include <random>
#include <variant>
/**
* @brief Most connections, hopefully all that are more sophisticated than just visuals or inside other Objects
* If something isn't working, you likely forgot to establish the connection here.
*/
void Control::makeConnections()
{
CuteControl* cc = &CuteControl::get();
......@@ -57,6 +60,19 @@ void Control::makeConnections()
&CuteControl::changeVerbosity);
}
/**
* @brief Blocking. Does setup and starts the Application.
* This is the equivalent to the classic minimal main() function of a Qt Widget App.
* MainWindow and QApplication are created, Control's connections established.
* Afterwards the Users setup() is called, so that all functionality is available.
* QApplication::exec() is blocking, so just before that, in the case of autorun being set,
* the appropriate thread is started.
* This works fine, because QApplications event queue is already created on construction,
* and will only processed on execution.
*
* @param userSetup Pointer to the User implemented Setup function.
* @return int return value of QApplication::exec() or -1 if called before exiting.
*/
int Control::run(void (*userSetup)())
{
static bool running = false;
......@@ -83,6 +99,12 @@ int Control::run(void (*userSetup)())
return -1;
}
/**
* @brief Construct a new Control::Control object
* Here, in a not at all dynamic way, the vectors for processing plot commands
* are created.
* @todo This really should not be hardcoded.
*/
Control::Control()
{
onTopSeries.emplace_back();
......@@ -93,42 +115,99 @@ Control::Control()
plotHistory.emplace_back();
}
/**
* @brief Appends a QString to MainWindows logging Area / textEdit.
*
* @param message The message to be appended.
*/
void Control::logMessage(const QString message)
{
w->textEdit->append(message);
}
/**
* @brief Sets the status bars progress bar to the given percentage. Only integer values are supported.
*
* @param percentage The Percentage 0 - 100, the processbar should show.
*/
void Control::setProgress(int percentage)
{
w->progressBar->setValue(percentage);
}
/**
* @brief Displays the given message in MainWindows status bar for duration_s seconds.
*
* @param message The QString to be displayed.
* @param duration_s Time in seconds, the message should stay. 0 will have the message only disappear when overwritten.
*/
void Control::setStatusMessage(const QString message, int duration_s)
{
w->statusBar->showMessage(message, duration_s * 1000);
}
/**
* @brief Show or hide the given plot
*
* @param plot The number of the plot to be manipulated. Starting from 0 for the left mose plot.
* @param visible Whether to show or hide.
* @todo ensure every graphing widget can hide
*/
void Control::setPlotVisible(int plot, bool visible)
{
w->graphingWidgets[plot]->setHidden(!visible);
}
/**
* @brief Change the given plots title in ChartMenu and in the Plot itself.
* The ChartMenu has a separate memory of the plot titles, so it it can show them without having to look them up,
* which would create complicated dependencies.
* @todo This will break, if other plotting widgets than QChart are added. Most easy thing would likely be,
* to offer setTile() as an interface in the new Widget and adjust the this->charts vector accordingly.
*
* @param plot The number of the plot to be manipulated. Starting from 0 for the left mose plot.
* @param title The new title.
*/
void Control::setPlotTitle(int plot, const QString title)
{
w->charts[plot]->setTitle(title);
w->cm->titleChanged(plot, title);
}
/**
* @brief Instruct the MainWindow to change the given plots theme to one of the themes built into QtCharts
* This will affect all and only QCharts.
*
* @param themeNumber 0-7 are valid.
*/
void Control::setPlotTheme(int themeNumber)
{
w->changeChartTheme(themeNumber);
}
/**
* @brief Whether the legend should be shown or hidden
*
* @param plot The number of the plot to be manipulated. Starting from 0 for the left mose plot.
* @param visible Whether to show or hide.
* @todo dynamic graphs...
*/
void Control::setLegendVisible(int plot, bool visible)
{
w->charts[plot]->legend()->setVisible(visible);
}
/**
* @brief Applies the given Titles to the axes of that plot. Hides the Title if empty.
* Manipulating the axes is a bit tedious, since we can only get a list of all axes from the chart.
* We then have to check it's properties to find the orientation.
*
* @param plot The plot to be manipulated.
* @param x Title for the x-axis.
* @param y Title for the y-axis.
* @todo dynamic graphs...
*/
void Control::setAxisTitles(int plot, QString x, QString y)
{
if ((size_t)plot >= w->charts.size())
......@@ -149,6 +228,14 @@ void Control::setAxisTitles(int plot, QString x, QString y)
}
}
/**
* @brief Show or hide the given plots axes.
*
* @param plot The plot to be manipulated.
* @param x Wether the x-axis should be visible.
* @param y Wether the y-axis should be visible.
* @todo dynamic graphs...
*/
void Control::setAxisVisible(int plot, bool x, bool y)
{
if ((size_t)plot >= w->charts.size())
......@@ -167,12 +254,25 @@ void Control::setAxisVisible(int plot, bool x, bool y)
}
}
/**
* @brief Add or "register" the given function to the Application
* The same order in both locations is crutial,
* as the index will be used to choose the threads function.
* @param func The function pointer to be called by the AlgoThread.
* @param name The name to be displayed in the ConfigPanels QCombobox algoBox.
*/
void Control::registerAlgorithm(void (*func)(), const QString name)
{
algorithms.emplace_back(func, name);
w->addAlgorithm(name);
}
/**
* @brief To be called when the AlgoThread should end before the Algorithm has ended.
* This will simply emit a signal to the AlgoThread, that it may please terminate.
* The User is responsible for running AlgoThread event loop and cleanly ending their function.
* cute::ok() is provided for that purpose.
*/
void Control::stopThread()
{
if (thread)
......@@ -181,6 +281,10 @@ void Control::stopThread()
}
}
/**
* @brief This should be called, when the tread finishes it's execution.abort
* The thread related variables and displays are reset here.
*/
void Control::threadEnded()
{
threadRunning = false;
......@@ -188,6 +292,18 @@ void Control::threadEnded()
thread = nullptr;
}
/**
* @brief Sets up and starts an AlgoThread.
* A new thread is created and connected such, that when finished, it notifies Control and flags itself for deletion.
* CuteControl is then handed it's problem and the currently set verbosity, so that it can start execution right away.
* Most importantly CuteControl is then moved to the EventQueue of the newly created thread.
* That has to be done, since CuteControl was created in the main thread and thus is hooked into the main EventLoop.
* This can only be done, pushing from the objects current thread, so it has to be moved back by the AlgoThread.
* When the objects are in different threads, the signals are automatically stored and processed in the receivers EventQueue.
* This way, it is thread safe.
*
* @param func The function/algorithm to be executed by the AlgoThread.
*/
void Control::startThread(void (*func)())
{
if (!thread)
......@@ -207,6 +323,10 @@ void Control::startThread(void (*func)())
}
}
/**
* @brief Depending on if a thread has already been started, either start or stop a thread.
* The appropriate algorithm is determined here from the current selection of the algoBox.
*/
void Control::onRunButton()
{
if (!thread)
......@@ -221,18 +341,35 @@ void Control::onRunButton()
}
}
/**
* @brief Change the problem widget stack to random generation and set the given size.
* The setProblem functions only manipulate the entries in the View.abort
* When a problem is to be generated, the necessary information will be pulled from the View.
* @param n The number to be entered into the QSpinBox.
*/
void Control::setProblemSize(int n)
{
w->configPanel->stackedWidget->setCurrentWidget(w->configPanel->randomWidget);
w->configPanel->problemSizeBox->setValue(n);
}
/**
* @brief Change the problem widget stack to reading from a file and set the path.
* The setProblem functions only manipulate the entries in the View.abort
* When a problem is to be generated, the necessary information will be pulled from the View.
* @param path The QString to be entered into the QLineEdit. No validity checks are performed here.
*/
void Control::setProblemFile(QString path)
{
w->configPanel->stackedWidget->setCurrentWidget(w->configPanel->fileWidget);
w->configPanel->fileLine->setText(path);
}
/**
* @brief Depending of if the problem was locked/retained or not, a new problem is generated or the old problem is used.
*
* @return std::vector<cute::Point> The given Problem. Newly generated if problemRetained was not set.
*/
std::vector<cute::Point> Control::getProblem()
{
if (!problemRetained)
......@@ -242,6 +379,20 @@ std::vector<cute::Point> Control::getProblem()
return problem;
}
/**
* @brief Big function, filling the problem member variable with the method selected in the GUI.
* The method depends on the current Widget of the ConfigPanel.
* For random generation, floats with 2 decimal places and to a maximum number of 100 are generated.
* These values are currently hard coded. The amount of numbers is read directly from the GUI.
*
* For reading a file, the CSVParser is used.
* The path is read directly from the GUI.
* Only lines with at least two fields and numbers in the first two fields are read.abort
* Other lines as well as data beyond the second column are simply discarted.
*
* For interpreting pasted or drag'n'dropped data, the CSVParser is used is the same way,
* with the exception of the string being handed to the parser rather than a filepath.
*/
void Control::generateProblem()
{
problem.clear();
......@@ -304,6 +455,10 @@ void Control::generateProblem()
}
}
/**
* @brief Resets the left most plot (plot0) and plots the problems Points to it.
* @todo getProblem is called here, but is that problem then used by the thread, if it is not locked? UX wise, that would make sense.
*/
void Control::onPreviewButton()
{
if (!threadRunning)
......@@ -313,6 +468,12 @@ void Control::onPreviewButton()
}
}
/**
* @brief Depending on the state, set problemRetained and show that in the View, or release them.
* The Problem is not overwritten, so it can be locked again.abort
* In case no problem has been generated before, one is generated.
* Another option would be to just do nothing in that case.
*/
void Control::onLockButton()
{
if (problemRetained)
......@@ -552,6 +713,11 @@ void Control::resizeAxes(int plot)
}
}
/**
* @brief Remove all series from the plot and the plots history and onTop vectors
* This currently only works with QCharts.
* @param plot The plot to be reset.
*/
void Control::resetPlot(int plot)
{
w->charts[plot]->removeAllSeries();
......@@ -663,6 +829,11 @@ void Control::setPlotScale(int plot, int x, int y)
resizeAxes(plot);
}
/**
* @brief Will write the current problem to a .csv file.
* The path is chosen by the User in a QFileDialog.
* To be called when the Menubars Save Button is clicked.
*/
void Control::saveProblem()
{
QString filter = "CSV File (*.csv)";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment