Commit c9c93aca authored by Yann Boucher's avatar Yann Boucher
Browse files

Boutons pour afficher l'aide pour les règles de transition avec rulestring

parent b03fd11b
Pipeline #79532 passed with stages
in 17 seconds
......@@ -118,6 +118,9 @@
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
......@@ -128,6 +131,9 @@
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>20</number>
</property>
</widget>
</item>
</layout>
......@@ -570,31 +576,32 @@ pattern recorded :</string>
<x>0</x>
<y>0</y>
<width>1068</width>
<height>22</height>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuFichier">
<property name="title">
<string>Fichier</string>
<string>File</string>
</property>
<addaction name="action_open_configuration"/>
</widget>
<widget class="QMenu" name="menuEditer">
<property name="title">
<string>Éditer</string>
<string>Edit</string>
</property>
<addaction name="actionCharger_depuis_une_image"/>
<addaction name="action_save_struct"/>
</widget>
<widget class="QMenu" name="menuA_propos">
<property name="title">
<string>À propos</string>
<string>About</string>
</property>
<addaction name="action_propos_de_Cellulut"/>
<addaction name="action_propos_de_Qt"/>
</widget>
<widget class="QMenu" name="menuBonus">
<property name="title">
<string>Bonus</string>
<string>Extra</string>
</property>
<addaction name="action_bad_apple"/>
</widget>
......@@ -606,7 +613,7 @@ pattern recorded :</string>
<widget class="QStatusBar" name="statusbar"/>
<action name="action_save_struct">
<property name="text">
<string>Sauvegarder la sélection</string>
<string>Save selection</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+S</string>
......@@ -614,17 +621,17 @@ pattern recorded :</string>
</action>
<action name="action_propos_de_Cellulut">
<property name="text">
<string>À propos de Cellulut</string>
<string>About Cellulut</string>
</property>
</action>
<action name="action_propos_de_Qt">
<property name="text">
<string>À propos de Qt</string>
<string>About Qt</string>
</property>
</action>
<action name="actionCharger_depuis_une_image">
<property name="text">
<string>Charger depuis une image...</string>
<string>Load from an image...</string>
</property>
</action>
<action name="action_bad_apple">
......@@ -632,6 +639,11 @@ pattern recorded :</string>
<string>Play &quot;Bad Apple!!&quot; animation</string>
</property>
</action>
<action name="action_open_configuration">
<property name="text">
<string>Open configuration</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
......
......@@ -35,6 +35,7 @@ Fichier définissant la classe Property représentant une propriété chargable,
#include "neighborhood.hpp"
#include "neighborhoodDialog.hpp"
struct HelpProperty;
struct StringProperty;
struct IntegerProperty;
struct CoordinateProperty;
......@@ -56,6 +57,7 @@ public:
virtual void visit(IntegerProperty& str) = 0;
virtual void visit(CoordinateProperty& coord) = 0;
virtual void visit(PropertyList& str) = 0;
virtual void visit(HelpProperty& str) = 0;
};
/**
......@@ -164,15 +166,13 @@ public:
\brief Représente un bouton permettant l'affichage d'un manuel.
**/
struct HelpProperty : public PropertyImpl<StringProperty>
struct HelpProperty : public PropertyImpl<HelpProperty>
{
public:
//! \brief Constructeur par défaut.
HelpProperty() = default;
/** \brief Constructeur avec valeur initiale.
\param initval Valeur initiale.
**/
HelpProperty(const std::string& initval)
HelpProperty(const std::string& initval = "")
: str(initval)
{}
......
......@@ -49,7 +49,7 @@ private:
//! \brief Représente une règle de transition totalistique configurable textuellement.
//! Le format d'une règle est tel que suit:
/**
## format d'une règle de transition générale (non-isotropique)
## Format d'une règle de transition générale (non-isotropique)
On associe un index (commençant) à 0 à chaque cellule du voisinnage, dans un ordre de gauche à droite et de haut en bas.
Le format est alors presque identique, à la seule différence que au lieu d'intervalles associés à des états, on a juste un état attendu à chaque position du voisinage:
......@@ -86,6 +86,40 @@ private:
private:
mutable std::vector<NonIsotropicRuleEntry> m_entries;
DEFINE_CONFIGURABLE_PROPERTY(StringProperty, rule_string, "Rule String");
DEFINE_CONFIGURABLE_PROPERTY(HelpProperty, help_string, "Help",
R"(
## Format d'une règle de transition générale (non-isotropique)
On associe un index (commençant) à 0 à chaque cellule du voisinnage, dans un ordre de gauche à droite et de haut en bas.
Le format est alors presque identique, à la seule différence que au lieu d'intervalles associés à des états, on a juste un état attendu à chaque position du voisinage:
```
etat_cellule, état_voisin_de_position_1, ..., état_voisin_de_position_1-> nouvel_etat
```
par exemple le voisinage :
```
**
*c*
* *
```
est énuméré ainsi:
```
01
2c3
4 5
```
et on peut créer par exemple cette règle:
```
0, 0, 1, 0, 0, 1, 1 -> 1
```
Les règles sont traitées dans l'ordre de leur écriture, si deux règles pourraient s'appliquer à une cellule et à un voisinage, on applique la première dans l'ordre des lignes, du haut vers le bas.
)");
};
......
......@@ -81,7 +81,7 @@ private:
//! \brief Représente une règle de transition totalistique configurable textuellement.
//! Le format d'une règle est tel que suit:
/**
## format d'une règle de transition isotropique:
## Format d'une règle de transition isotropique:
etat_cellule, x:intervalle_voisins_d'etat_x, ... -> nouvel_etat
......@@ -130,7 +130,50 @@ private:
private:
mutable std::vector<TotalisticRuleEntry> m_entries;
DEFINE_CONFIGURABLE_PROPERTY(StringProperty, rule_string, "Rule String");
DEFINE_CONFIGURABLE_PROPERTY(HelpProperty, help_string, "All your base are belong to us");
DEFINE_CONFIGURABLE_PROPERTY(HelpProperty, help_string, "Help",
R"(
## Format d'une règle de transition isotropique:
etat_cellule, x:intervalle_voisins_d'etat_x, ... -> nouvel_etat
expression := <expression mathématique pouvant contenir une variable qu'on associerait à l'état initial>
intervalle := [expression..expression] | [expression] | '*'
Exemple automate cellulaire cyclique de Griffith:
```
i, (i+1)%3:[3] -> (i+1)%3
```
Exemple jeu de la vie:
```
0,0:* ,1:[3]->1 (une cellule morte devient vivante si elle a exactement 3 voisisin vivants)
1,0:[0..1],1:* ->0 (une cellule vivante meurt si elle a 0 ou 1 voisins vivants)
1,0:[4..*],1:* ->0 (une cellule vivante meurt si elle a 4 ou plus voisins vivants)
```
Exemple Wireworld: (https://xalava.github.io/WireWorld/)
```
1->2
2->3
3,1:[1..2]->1
```
Exemple Brain's Brain: (https://www.conwaylife.com/wiki/OCA:Brian%27s_Brain)
```
0,1:[2]->1
2->0
```
Si il n'y a pas de règle correspondat à une cellule et son voisinage, alors cette cellule ne change pas d'état.
Les intervalles non mentionnés dans la règle sont considérés par défaut comme des '*'.
Les règles sont traitées dans l'ordre de leur écriture, si deux règles pourraient s'appliquer à une cellule et à un voisinage, on applique la première dans l'ordre des lignes, du haut vers le bas.
)");
};
#endif // TOTALISTICTRANSITIONRULE_HPP
......@@ -59,6 +59,7 @@ MainWindow::MainWindow(QWidget *parent)
});
connect(ui->transition_list, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int)
{ update_transition_settings(); });
connect(ui->action_open_configuration, &QAction::triggered, this, [this] { on_openPatternButton_clicked(); });
connect(ui->action_bad_apple, &QAction::triggered, this, &MainWindow::play_bad_apple);
connect(ui->action_propos_de_Cellulut, &QAction::triggered, this, [this](bool)
{
......@@ -709,11 +710,15 @@ void MainWindow::play_bad_apple()
ui->grid_view->copy_grid(grid);
});
};
// On coupe la simulation si elle est en train de s'exécuter
if (timer->isActive())
{
on_playPauseButton_clicked();
}
;
#ifdef BAD_APPLE_AUDIO
bad_apple_player.setMedia(QUrl::fromLocalFile("extras/bad-apple.wav"));
bad_apple_player.play();
#else
......@@ -721,7 +726,7 @@ void MainWindow::play_bad_apple()
bad_apple_elapsed.start();
#endif
bad_apple_timer.start(24);
bad_apple_timer.start(11);
statusBar()->showMessage("Original : \"Bad Apple!!\" feat. Nomico by Alstroemeria Records", 60000);
}
......
......@@ -3,6 +3,11 @@ QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
equals(QT_MAJOR_VERSION, 5): QT += multimedia
!versionAtLeast(QT_VERSION, 5.14.0) {
message("Cannot use Qt $${QT_VERSION}")
error("Use Qt 5.14 or newer")
}
CONFIG += c++14
TEMPLATE = app
......
......@@ -134,10 +134,15 @@ void UIBuilderVisitor::visit(HelpProperty& prop)
{
QPushButton* button = new QPushButton("Help", current_widget());
add_widget("", button);
QString msg = QString::fromStdString(prop.str);
QObject::connect(button, &QPushButton::clicked,
[&prop]() {
QMessageBox::information(NULL, "Help", QString::fromStdString(prop.str));
[msg]() {
QMessageBox* box = new QMessageBox(QMessageBox::NoIcon, "Help", msg,
QMessageBox::Ok);
box->setTextFormat(Qt::MarkdownText);
box->setTextInteractionFlags(Qt::TextBrowserInteraction);
box->show();
});
}
......
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