Kapitel 8
Alle Codedateien dieses Kapitels herunterladen
08_2_1_HelloWorldGUI.cpp
#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>
int main()
{
// Ein Nana-Formular als Basis des Fensters anlegen
nana::form window;
window.caption("C++ Schnelleinstieg");
// Ein Text-Label anlegen. Es soll zentriert sein.
nana::label textLabel(window, "Hallo Welt!");
textLabel.text_align(nana::align::center, nana::align_v::center);
// Das Label dem Layout hinzufügen
window.div("<myText>");
window["myText"] << textLabel;
window.collocate();
// Fenster anzeigen und Nana starten
window.show();
nana::exec();
return 0;
}
08_2_2_HelloWorldButton.cpp
#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/button.hpp>
int main()
{
// Ein Nana-Formular als Basis des Fensters anlegen
nana::form window;
window.caption("C++ Schnelleinstieg");
// Ein Text-Label anlegen. Es soll zentriert sein.
nana::label textLabel(window, "Hallo Welt!");
textLabel.text_align(nana::align::center, nana::align_v::center);
// Eine Schaltfläche mit Click-Funktion anlegen
nana::button button(window, "Beenden");
button.events().click([&]() {
window.close();
});
// Beide Elemente dem Layout hinzufügen
window.div("vertical <myText><button>");
window["myText"] << textLabel;
window["button"] << button;
window.collocate();
// Fenster anzeigen und Nana starten
window.show();
nana::exec();
return 0;
}
08_3_Callbacks.cpp
#include <iostream>
#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/button.hpp>
int main()
{
// Ein Nana-Formular als Basis des Fensters anlegen
nana::form window;
window.caption("C++ Schnelleinstieg");
// Ein Text-Label anlegen. Es soll zentriert sein.
nana::label textLabel(window, "Hallo Welt!");
textLabel.text_align(nana::align::center, nana::align_v::center);
// Eine Schaltfläche mit Click-Funktion anlegen
nana::button button(window, "Beenden");
button.events().click([&]() {
window.close();
});
// Ein Resize-Event registrieren
window.events().resizing(
[](const nana::arg_resizing& a)
{
// arg_resizing ist ein struct, in dem die Größe steht
std::cout << a.width << "x" << a.height << std::endl;
});
// Beide Elemente dem Layout hinzufügen
window.div("vertical <myText><button>");
window["myText"] << textLabel;
window["button"] << button;
window.collocate();
// Fenster anzeigen und Nana starten
window.show();
nana::exec();
return 0;
}
08_4_1_Lernkarten.cpp
#include <iostream>
#include <string>
#include <vector>
#include <nana/gui.hpp>
#include <nana/gui/msgbox.hpp>
#include <nana/gui/place.hpp>
#include <nana/gui/widgets/button.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/panel.hpp>
#include <nana/gui/widgets/tabbar.hpp>
#include <nana/gui/widgets/textbox.hpp>
struct Question
{
Question(const std::string& q, const std::string& a, int c)
: question(q), answer(a), category(c)
{
}
std::string question;
std::string answer;
int category = 0;
};
class QuestionManager
{
public:
void promote(const Question& question)
{
// Frage wurde richtig beantwortet und soll eins weiter
move(question, question.category + 1);
}
void degrade(const Question& question)
{
// Falsch beantwortet - zurück in die erste Kategorie
move(question, 0);
}
std::vector<Question> getQuestions(int category)
{
// Suche alle Fragen aus der gewünschten Kategorie
std::vector<Question> result;
for (Question stored : questions)
{
if (stored.category == category)
{
result.push_back(stored);
}
}
return result;
}
void addQuestion(const std::string& question,
const std::string& answer)
{
questions.push_back(Question(question, answer, 0));
}
private:
void move(const Question& question, int newCategory)
{
// Wichtig: Per Referenz iterieren. & nicht vergessen!
for (Question& stored : questions)
{
if (stored.question == question.question)
{
stored.category = newCategory;
if (stored.category > maxCategories)
{
// Darf nicht höher als das Maximum liegen
stored.category = maxCategories;
}
if (stored.category < 0)
{
// Der kleinste Index muss null sein
stored.category = 0;
}
// Frage wurde gefunden und verschoben
return;
}
}
std::cerr << "changeCategory: Could not find '"
<< question.question << "'" << std::endl;
}
const int maxCategories = 2; // Drei Kategorien (inkl 0)
std::vector<Question> questions;
};
class LearnTab : public nana::panel<false>
{
private:
nana::place content;
nana::label header; // Frage X von Y
nana::label questionHeader; // Frage:
nana::label question;
nana::label answerHeader; // Antwort:
nana::textbox answer; // Eingabefeld für die Antwort
nana::button button; // Antworten
QuestionManager& manager;
const int category;
std::vector<Question> questions;
int currentQuestionIndex = 0;
public:
LearnTab(nana::window window, QuestionManager& m, int c)
: nana::panel<false>(window),
manager(m), category(c),
content(*this), header(*this),
questionHeader(*this), question(*this),
answerHeader(*this), answer(*this), button(*this)
{
content.div("vertical margin=10"
"<header>"
"<<questionHeader><question>>"
"<height=30 <answerHeader fit><answer><button fit>>");
content["header"] << header;
content["questionHeader"] << questionHeader;
content["question"] << question;
content["answerHeader"] << answerHeader;
content["answer"] << answer;
content["button"] << button;
header.text_align(nana::align::center, nana::align_v::center);
questionHeader.caption("Frage:");
answerHeader.caption("Antwort:");
answer.multi_lines(false);
button.caption("Antworten");
events().expose(
[&](nana::arg_expose arg)
{
if (arg.exposed) // Element ist sichtbar geworden
{
// Die Fragen neu einlesen und die erste anzeigen
refresh();
}
});
button.events().click([&]()
{
if (currentQuestionIndex < 0
|| currentQuestionIndex >= questions.size())
{
// Aktuell ist keine Frage im Tab aktiv
return;
}
evaluateAnswer(questions.at(currentQuestionIndex),
answer.text());
layoutNextQuestion();
});
// Die Fragen einlesen und die erste anzeigen
refresh();
}
void refresh()
{
// Lade die Fragen für diese Kategorie
questions = manager.getQuestions(category);
currentQuestionIndex = -1;
layoutNextQuestion();
}
// Klassen können auch mehrere private Abschnitte haben:
private:
void layoutNextQuestion()
{
currentQuestionIndex++;
if (currentQuestionIndex >= questions.size())
{
// Die Fragen neu laden und vom Anfang beginnen
questions = manager.getQuestions(category);
currentQuestionIndex = 0;
}
if (questions.size() == 0)
{
header.caption("Keine Fragen in dieser Kategorie");
question.caption("");
return;
}
std::string headline = "Frage "
+ std::to_string(currentQuestionIndex + 1)
+ " von " + std::to_string(questions.size());
header.caption(headline);
Question q = questions.at(currentQuestionIndex);
// Formatmodus aktivieren und mit <bold></> fett machen
question.format(true);
question.caption("<bold>" + q.question + "</>");
}
void evaluateAnswer(const Question& reference,
const std::string& userAnswer)
{
nana::msgbox msg("Die Antwort ist...");
if (userAnswer == reference.answer)
{
manager.promote(reference);
msg << "Korrekt!";
}
else
{
manager.degrade(reference);
msg.icon(nana::msgbox::icon_error);
msg << "Leider Falsch!";
}
msg.show();
}
};
int main()
{
QuestionManager manager;
manager.addQuestion("Schleife", "Loop");
manager.addQuestion("Klasse", "Class");
manager.addQuestion("Zeichenkette", "String");
// (1) Ein Nana-Formular als Basis des Fensters anlegen
// Das Fenster ist 500x250 Pixel groß.
// ===================================================
nana::form window(nana::API::make_center(500, 250));
window.caption("Lernkarten");
// (2) Grundlayout festlegen und Elemente verknüpfen
// ===================================================
LearnTab tab(window, manager, 0);
window.div("<tab>");
window["tab"] << tab;
// (3) Fenster anzeigen und Nana starten
// ===================================================
window.collocate();
window.show();
nana::exec();
return 0;
}
08_4_2_TextFormat.cpp
#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>
int main()
{
// Ein Nana-Formular als Basis des Fensters anlegen
nana::form window;
window.caption("Textformatierung");
nana::label labelA(window);
nana::label labelB(window);
nana::label labelC(window);
nana::label labelD(window);
labelA.format(true);
labelA.caption("Teilweise <bold>fett</>");
labelB.format(true);
labelB.caption("<blue>Blau</> <red>Rot</> Schwarz");
labelC.format(true);
labelC.caption("<size=20>Riesig</> Klein");
labelD.format(true);
labelD.caption("<bold blue>Fettes Blau</>");
// Die Label dem Layout hinzufügen
window.div("vertical margin=10 <a><b><c><d>");
window["a"] << labelA;
window["b"] << labelB;
window["c"] << labelC;
window["d"] << labelD;
window.collocate();
// Fenster anzeigen und Nana starten
window.show();
nana::exec();
return 0;
}
08_4_3_LernkartenMehrereTabs.cpp
#include <iostream>
#include <string>
#include <vector>
#include <nana/gui.hpp>
#include <nana/gui/msgbox.hpp>
#include <nana/gui/place.hpp>
#include <nana/gui/widgets/button.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/panel.hpp>
#include <nana/gui/widgets/tabbar.hpp>
#include <nana/gui/widgets/textbox.hpp>
struct Question
{
Question(const std::string& q, const std::string& a, int c)
: question(q), answer(a), category(c)
{
}
std::string question;
std::string answer;
int category = 0;
};
class QuestionManager
{
public:
void promote(const Question& question)
{
// Frage wurde richtig beantwortet und soll eins weiter
move(question, question.category + 1);
}
void degrade(const Question& question)
{
// Falsch beantwortet - zurück in die erste Kategorie
move(question, 0);
}
std::vector<Question> getQuestions(int category)
{
// Suche alle Fragen aus der gewünschten Kategorie
std::vector<Question> result;
for (Question stored : questions)
{
if (stored.category == category)
{
result.push_back(stored);
}
}
return result;
}
void addQuestion(const std::string& question,
const std::string& answer)
{
questions.push_back(Question(question, answer, 0));
}
private:
void move(const Question& question, int newCategory)
{
// Wichtig: Per Referenz iterieren. & nicht vergessen!
for (Question& stored : questions)
{
if (stored.question == question.question)
{
stored.category = newCategory;
if (stored.category > maxCategories)
{
// Darf nicht höher als das Maximum liegen
stored.category = maxCategories;
}
if (stored.category < 0)
{
// Der kleinste Index muss null sein
stored.category = 0;
}
// Frage wurde gefunden und verschoben
return;
}
}
std::cerr << "changeCategory: Could not find '"
<< question.question << "'" << std::endl;
}
const int maxCategories = 2; // Drei Kategorien (inkl 0)
std::vector<Question> questions;
};
class LearnTab : public nana::panel<false>
{
private:
nana::place content;
nana::label header; // Frage X von Y
nana::label questionHeader; // Frage:
nana::label question;
nana::label answerHeader; // Antwort:
nana::textbox answer; // Eingabefeld für die Antwort
nana::button button; // Antworten
QuestionManager& manager;
const int category;
std::vector<Question> questions;
int currentQuestionIndex = 0;
public:
LearnTab(nana::window window, QuestionManager& m, int c)
: nana::panel<false>(window),
manager(m), category(c),
content(*this), header(*this),
questionHeader(*this), question(*this),
answerHeader(*this), answer(*this), button(*this)
{
content.div("vertical margin=10"
"<header>"
"<<questionHeader><question>>"
"<height=30 <answerHeader fit><answer><button fit>>");
content["header"] << header;
content["questionHeader"] << questionHeader;
content["question"] << question;
content["answerHeader"] << answerHeader;
content["answer"] << answer;
content["button"] << button;
header.text_align(nana::align::center, nana::align_v::center);
questionHeader.caption("Frage:");
answerHeader.caption("Antwort:");
answer.multi_lines(false);
button.caption("Antworten");
events().expose(
[&](nana::arg_expose arg)
{
if (arg.exposed) // Element ist sichtbar geworden
{
// Die Fragen neu einlesen und die erste anzeigen
refresh();
}
});
button.events().click([&]()
{
if (currentQuestionIndex < 0
|| currentQuestionIndex >= questions.size())
{
// Aktuell ist keine Frage im Tab aktiv
return;
}
evaluateAnswer(questions.at(currentQuestionIndex),
answer.text());
layoutNextQuestion();
});
// Die Fragen einlesen und die erste anzeigen
refresh();
}
void refresh()
{
// Lade die Fragen für diese Kategorie
questions = manager.getQuestions(category);
currentQuestionIndex = -1;
layoutNextQuestion();
}
// Klassen können auch mehrere private Abschnitte haben:
private:
void layoutNextQuestion()
{
currentQuestionIndex++;
if (currentQuestionIndex >= questions.size())
{
// Die Fragen neu laden und vom Anfang beginnen
questions = manager.getQuestions(category);
currentQuestionIndex = 0;
}
if (questions.size() == 0)
{
header.caption("Keine Fragen in dieser Kategorie");
question.caption("");
return;
}
std::string headline = "Frage "
+ std::to_string(currentQuestionIndex + 1)
+ " von " + std::to_string(questions.size());
header.caption(headline);
Question q = questions.at(currentQuestionIndex);
// Formatmodus aktivieren und mit <bold></> fett machen
question.format(true);
question.caption("<bold>" + q.question + "</>");
}
void evaluateAnswer(const Question& reference,
const std::string& userAnswer)
{
nana::msgbox msg("Die Antwort ist...");
if (userAnswer == reference.answer)
{
manager.promote(reference);
msg << "Korrekt!";
}
else
{
manager.degrade(reference);
msg.icon(nana::msgbox::icon_error);
msg << "Leider Falsch!";
}
msg.show();
}
};
int main()
{
QuestionManager manager;
manager.addQuestion("Schleife", "Loop");
manager.addQuestion("Klasse", "Class");
manager.addQuestion("Zeichenkette", "String");
// (1) Ein Nana-Formular als Basis des Fensters anlegen
// ===================================================
nana::form window(nana::API::make_center(500, 250));
window.caption("Lernkarten");
// (2) Grundlayout festlegen und Elemente verknüpfen
// ===================================================
window.div("vertical "
"<height=30 <>|20%<button>>"
"<tabBar height=30>"
"<tabFrame>");
// Eine Schaltfläche anlegen. Aktuell noch ohne Funktion
nana::button button(window);
window["button"] << button;
// Navigationsleiste für Tabs hinzufügen
nana::tabbar<std::string> tabBar(window);
window["tabBar"] << tabBar;
// (3) Nun die Elemente mit Leben füllen
// ===================================================
// Drei Tabs für die drei Lernkategorien anlegen
LearnTab learnCategory1(window, manager, 0);
LearnTab learnCategory2(window, manager, 1);
LearnTab learnCategory3(window, manager, 2);
window["tabFrame"]
.fasten(learnCategory1)
.fasten(learnCategory2)
.fasten(learnCategory3);
tabBar
.append("Kategorie 1", learnCategory1)
.append("Kategorie 2", learnCategory2)
.append("Kategorie 3", learnCategory3);
// Aktiviere die erste Kategorie
tabBar.activated(0);
// (4) Fenster anzeigen und Nana starten
// ===================================================
window.collocate();
window.show();
nana::exec();
return 0;
}
08_5_1_Dateiarbeit.cpp
#include <fstream>
#include <string>
#include <iostream>
int main()
{
const std::string filePath = "test.txt";
// ofstream steht für "output file stream"
std::ofstream outputFile(filePath);
outputFile << "Eine Testausgabe";
// Die Datei muss geschlossen werden, damit sie
// geschrieben wird
outputFile.close();
std::cout << "-- Datei geschrieben --" << std::endl;
// ifstream steht für "input file stream"
std::ifstream inputFile(filePath);
if (!inputFile.good())
{
std::cerr << "Konnte Datei " << filePath
<< " nicht lesend \224ffnen!" << std::endl;
return 1;
}
std::string textFromFile;
std::getline(inputFile, textFromFile);
std::cout << "Inhalt: " << textFromFile << std::endl;
return 0;
}
08_5_2_LernkartenSpeichern.cpp
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <nana/gui.hpp>
#include <nana/gui/msgbox.hpp>
#include <nana/gui/place.hpp>
#include <nana/gui/widgets/button.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/panel.hpp>
#include <nana/gui/widgets/tabbar.hpp>
#include <nana/gui/widgets/textbox.hpp>
struct Question
{
Question(const std::string& q,const std::string& a,int c)
: question(q), answer(a), category(c)
{
}
std::string question;
std::string answer;
int category = 0;
};
class QuestionManager
{
public:
void promote(const Question& question)
{
// Frage wurde richtig beantwortet und soll eins weiter
move(question, question.category + 1);
}
void degrade(const Question& question)
{
// Falsch beantwortet - zurück in die erste Kategorie
move(question, 0);
}
std::vector<Question> getQuestions(int category)
{
// Suche alle Fragen aus der gewünschten Kategorie
std::vector<Question> result;
for (Question stored : questions)
{
if (stored.category == category)
{
result.push_back(stored);
}
}
return result;
}
void addQuestion(const std::string& question,
const std::string& answer)
{
questions.push_back(Question(question, answer, 0));
}
void save(const std::string& filePath)
{
// ofstream steht für "output file stream"
std::ofstream file(filePath);
for (Question question : questions)
{
file << question.question << "\n"
<< question.answer << "\n"
<< question.category;
// Eine leere Zeile trennt die Einträge
file << "\n\n";
}
}
void load(const std::string& filePath)
{
// ifstream steht für "input file stream"
std::ifstream file(filePath);
if (!file.good())
{
std::cerr << "Fragendatei " << filePath
<< " existiert nicht" << std::endl;
return;
}
// Fragen löschen und neu einlesen
questions.clear();
std::string question;
std::string answer;
std::string category;
while (true)
{
std::getline(file, question);
std::getline(file, answer);
std::getline(file, category);
if (!file.good())
{
// Wenn das Einlesen fehlgeschlagen ist, sind wir
// entweder am Ende der Datei, oder es gab einen
// anderen Fehler. Daher verlassen wir die Schleife
break;
}
questions.push_back(Question(question, answer,
std::stoi(category)));
// Leere Zeile am Ende jeden Eintrags überspringen
std::getline(file, question);
}
}
private:
void move(const Question& question, int newCategory)
{
// Wichtig: Per Referenz iterieren. & nicht vergessen!
for (Question& stored : questions)
{
if (stored.question == question.question)
{
stored.category = newCategory;
if (stored.category > maxCategories)
{
// Darf nicht höher als das Maximum liegen
stored.category = maxCategories;
}
if (stored.category < 0)
{
// Der kleinste Index muss null sein
stored.category = 0;
}
// Frage wurde gefunden und verschoben
return;
}
}
std::cerr << "changeCategory: Could not find '"
<< question.question << "'" << std::endl;
}
const int maxCategories = 2; // Drei Kategorien (inkl 0)
std::vector<Question> questions;
};
class LearnTab : public nana::panel<false>
{
private:
nana::place content;
nana::label header; // Frage X von Y
nana::label questionHeader; // Frage:
nana::label question;
nana::label answerHeader; // Antwort:
nana::textbox answer; // Eingabefeld für die Antwort
nana::button button; // Antworten
QuestionManager& manager;
const int category;
std::vector<Question> questions;
int currentQuestionIndex = 0;
public:
LearnTab(nana::window window, QuestionManager& m, int c)
: nana::panel<false>(window),
manager(m), category(c),
content(*this), header(*this),
questionHeader(*this), question(*this),
answerHeader(*this), answer(*this), button(*this)
{
content.div("vertical margin=10"
"<header>"
"<<questionHeader><question>>"
"<height=30 <answerHeader fit><answer><button fit>>");
content["header"] << header;
content["questionHeader"] << questionHeader;
content["question"] << question;
content["answerHeader"] << answerHeader;
content["answer"] << answer;
content["button"] << button;
header.text_align(nana::align::center,
nana::align_v::center);
questionHeader.caption("Frage:");
answerHeader.caption("Antwort:");
answer.multi_lines(false);
button.caption("Antworten");
events().expose(
[&](nana::arg_expose arg)
{
if (arg.exposed) // Element ist sichtbar geworden
{
// Die Fragen neu einlesen und die erste anzeigen
refresh();
}
});
button.events().click([&]()
{
if (currentQuestionIndex < 0
|| currentQuestionIndex >= questions.size())
{
// Aktuell ist keine Frage im Tab aktiv
return;
}
evaluateAnswer(questions.at(currentQuestionIndex),
answer.text());
layoutNextQuestion();
});
// Die Fragen einlesen und die erste anzeigen
refresh();
}
void refresh()
{
// Lade die Fragen für diese Kategorie
questions = manager.getQuestions(category);
currentQuestionIndex = -1;
layoutNextQuestion();
}
// Klassen können auch mehrere private Abschnitte haben:
private:
void layoutNextQuestion()
{
currentQuestionIndex++;
if (currentQuestionIndex >= questions.size())
{
// Die Fragen neu laden und vom Anfang beginnen
questions = manager.getQuestions(category);
currentQuestionIndex = 0;
}
if (questions.size() == 0)
{
header.caption("Keine Fragen in dieser Kategorie");
question.caption("");
return;
}
std::string headline = "Frage "
+ std::to_string(currentQuestionIndex + 1)
+ " von " + std::to_string(questions.size());
header.caption(headline);
Question q = questions.at(currentQuestionIndex);
// Formatmodus aktivieren und mit <bold></> fett machen
question.format(true);
question.caption("<bold>" + q.question + "</>");
}
void evaluateAnswer(const Question& reference,
const std::string& userAnswer)
{
nana::msgbox msg("Die Antwort ist...");
if (userAnswer == reference.answer)
{
manager.promote(reference);
msg << "Korrekt!";
}
else
{
manager.degrade(reference);
msg.icon(nana::msgbox::icon_error);
msg << "Leider Falsch!";
}
msg.show();
}
};
class AddingWindow : public nana::form
{
public:
AddingWindow(nana::window owner, QuestionManager& manager)
: nana::form(owner, nana::size(300, 90)),
question(*this), answer(*this), button(*this)
{
caption("Frage hinzufügen");
div("vertical"
"<question>"
"<answer>"
"<button>");
(*this)["question"] << question;
(*this)["answer"] << answer;
(*this)["button"] << button;
question.tip_string("Frage:");
question.multi_lines(false);
answer.tip_string("Antwort:");
answer.multi_lines(false);
button.caption("Hinzufügen");
button.events().click([&]()
{
std::string questionText = question.text();
std::string answerText = answer.text();
if (questionText.empty() || answerText.empty())
{
// Eine Fehlernachricht anzeigen
nana::msgbox msg("Eingabefehler!");
msg.icon(nana::msgbox::icon_error);
msg << "Geben Sie Frage und Antwort ein";
msg.show();
}
else
{
// Frage hinzufügen und die Eingabemaske leeren
manager.addQuestion(questionText, answerText);
question.caption("");
answer.caption("");
}
});
}
void show()
{
collocate();
// Genau wie show() zeigt modality() das Fenster an,
// der Unterschied ist jedoch, dass die Ausführung
// wartet, bis das Fenster wieder geschlossen wurde.
// Nur bei der msgbox wartet show() automatisch, bei
// Fenstern nicht.
modality();
}
private:
nana::form window;
nana::textbox question;
nana::textbox answer;
nana::button button;
};
int main()
{
const std::string questionFilePath = "questions.txt";
QuestionManager manager;
manager.load(questionFilePath);
// (1) Ein Nana-Formular als Basis des Fensters anlegen
// ===================================================
nana::form window(nana::API::make_center(500, 250));
window.caption("Lernkarten");
// (2) Grundlayout festlegen und Elemente verknüpfen
// ===================================================
window.div("vertical "
"<height=30 <>|20%<button>>"
"<tabBar height=30>"
"<tabFrame>");
// Eine Schaltfläche anlegen
nana::button button(window);
window["button"] << button;
// Navigationsleiste für Tabs hinzufügen
nana::tabbar<std::string> tabBar(window);
window["tabBar"] << tabBar;
// (3) Nun die Elemente mit Leben füllen
// ===================================================
// Drei Tabs für die drei Lernkategorien anlegen
LearnTab learnCategory1(window, manager, 0);
LearnTab learnCategory2(window, manager, 1);
LearnTab learnCategory3(window, manager, 2);
window["tabFrame"]
.fasten(learnCategory1)
.fasten(learnCategory2)
.fasten(learnCategory3);
tabBar
.append("Kategorie 1", learnCategory1)
.append("Kategorie 2", learnCategory2)
.append("Kategorie 3", learnCategory3);
// Aktiviere die erste Kategorie
tabBar.activated(0);
// Click-Event für den Button hinzufügen
button.caption("Hinzufügen");
button.events().click([&]()
{
AddingWindow addingWindow(window, manager);
addingWindow.show();
// Neue Fragen hinzugefügt. Lade erste Kategorie neu
learnCategory1.refresh();
manager.save(questionFilePath);
});
// (4) Fenster anzeigen und Nana starten
// ===================================================
window.collocate();
window.show();
nana::exec();
// (5) Vor Beenden des Programms Fortschritt speichern
// ===================================================
manager.save(questionFilePath);
return 0;
}