diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index faf5031..ef689cc 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -22,4 +22,4 @@ FetchContent_MakeAvailable(googletest) find_package(PkgConfig REQUIRED) # Check for gtkmm-4.0 specifically, not just gtk4 -pkg_check_modules(GTKMM REQUIRED gtkmm-4.0) \ No newline at end of file +pkg_check_modules(GTKMM REQUIRED gtkmm-4.0) diff --git a/src/ap/CMakeLists.txt b/src/ap/CMakeLists.txt index 7e9ae84..00c999a 100644 --- a/src/ap/CMakeLists.txt +++ b/src/ap/CMakeLists.txt @@ -18,4 +18,4 @@ target_sources(ap target_link_libraries(ap PRIVATE gtk4-settings) add_subdirectory(mvc) -# add_subdirectory(mvvm) \ No newline at end of file +# add_subdirectory(mvvm) diff --git a/src/ap/README.md b/src/ap/README.md index 0eaf53b..030a31f 100644 --- a/src/ap/README.md +++ b/src/ap/README.md @@ -46,11 +46,11 @@ View → Controller → Model ### 4. Examples ### 4.1. simple_ap -- Cos: +- Pros: - Quick, Simple -- Pos: +- Cons: - Dependency: e.g. what happen when we delete Gtk::Label m_labelMonitorA; - Scalability: - Reusability: -### 4.2. mvc_ap \ No newline at end of file +### 4.2. mvc_ap diff --git a/src/ap/mvc/CMakeLists.txt b/src/ap/mvc/CMakeLists.txt index 48ddf03..c265c19 100644 --- a/src/ap/mvc/CMakeLists.txt +++ b/src/ap/mvc/CMakeLists.txt @@ -9,4 +9,4 @@ target_sources(mvc_ap controller/Controller.cpp ) -target_link_libraries(mvc_ap PRIVATE gtk4-settings) \ No newline at end of file +target_link_libraries(mvc_ap PRIVATE gtk4-settings) diff --git a/src/ap/mvc/IObserver.h b/src/ap/mvc/IObserver.h index 60c9baf..2c4ed75 100644 --- a/src/ap/mvc/IObserver.h +++ b/src/ap/mvc/IObserver.h @@ -1,7 +1,8 @@ #pragma once +#include class IObserver { public: virtual ~IObserver() = default; virtual void onDataChanged(const std::string& newData) = 0; -}; \ No newline at end of file +}; diff --git a/src/ap/mvc/controller/Controller.cpp b/src/ap/mvc/controller/Controller.cpp index 843268a..b86d412 100644 --- a/src/ap/mvc/controller/Controller.cpp +++ b/src/ap/mvc/controller/Controller.cpp @@ -9,4 +9,4 @@ void Controller::updateRequest(const std::string& text) { // the Controller updates the Model when receiving new data from the View, // which then notifies all Views of the change model_->setData(text); -} \ No newline at end of file +} diff --git a/src/ap/mvc/controller/Controller.h b/src/ap/mvc/controller/Controller.h index 37198f5..487b264 100644 --- a/src/ap/mvc/controller/Controller.h +++ b/src/ap/mvc/controller/Controller.h @@ -10,4 +10,4 @@ class Controller { private: std::shared_ptr model_; -}; \ No newline at end of file +}; diff --git a/src/ap/mvc/model/SharedData.cpp b/src/ap/mvc/model/SharedData.cpp index 0f44a39..1f44c28 100644 --- a/src/ap/mvc/model/SharedData.cpp +++ b/src/ap/mvc/model/SharedData.cpp @@ -20,4 +20,4 @@ void SharedData::addObserver(IObserver* obs) { std::string SharedData::getData() const { return data_; -} \ No newline at end of file +} diff --git a/src/ap/mvc/model/SharedData.h b/src/ap/mvc/model/SharedData.h index 83f3349..ddac039 100644 --- a/src/ap/mvc/model/SharedData.h +++ b/src/ap/mvc/model/SharedData.h @@ -18,4 +18,4 @@ class SharedData { private: std::string data_; std::vector observers_; -}; \ No newline at end of file +}; diff --git a/src/ap/mvc/mvc_ap.cpp b/src/ap/mvc/mvc_ap.cpp index e6cb20c..aa31661 100644 --- a/src/ap/mvc/mvc_ap.cpp +++ b/src/ap/mvc/mvc_ap.cpp @@ -71,4 +71,4 @@ ContainerWindow::ContainerWindow() int main(int argc, char* argv[]) { auto app = Gtk::Application::create("org.gtkmm.example.singlemvc"); return app->make_window_and_run(argc, argv); -} \ No newline at end of file +} diff --git a/src/ap/mvc/view/DisplayWidget.cpp b/src/ap/mvc/view/DisplayWidget.cpp index 9686cbc..63599f2 100644 --- a/src/ap/mvc/view/DisplayWidget.cpp +++ b/src/ap/mvc/view/DisplayWidget.cpp @@ -3,8 +3,8 @@ DisplayWidget::DisplayWidget(const std::string& title, const std::string& color, const std::string& startData) : Gtk::Box(Gtk::Orientation::VERTICAL), - color_(color), - innerBox_(Gtk::Orientation::VERTICAL) { + innerBox_(Gtk::Orientation::VERTICAL), + color_(color) { frame_.set_label(title); frame_.set_margin(10); @@ -18,12 +18,13 @@ DisplayWidget::DisplayWidget(const std::string& title, const std::string& color, } void DisplayWidget::updateLabel(const std::string& text) { - // Use HTML markup to change text color + // Escape text to prevent Pango markup injection + auto escaped = Glib::Markup::escape_text(text); std::string markup = "" + text + ""; + "' size='x-large' weight='bold'>" + escaped + ""; labelData_.set_markup(markup); } void DisplayWidget::onDataChanged(const std::string& newData) { updateLabel(newData); -} \ No newline at end of file +} diff --git a/src/ap/mvc/view/DisplayWidget.h b/src/ap/mvc/view/DisplayWidget.h index a3e882f..e881d9f 100644 --- a/src/ap/mvc/view/DisplayWidget.h +++ b/src/ap/mvc/view/DisplayWidget.h @@ -1,6 +1,7 @@ +#pragma once #include #include "../IObserver.h" -#include "../controller/Controller.h" + class DisplayWidget : public Gtk::Box, public IObserver { public: DisplayWidget(const std::string& title, const std::string& color, @@ -14,4 +15,4 @@ class DisplayWidget : public Gtk::Box, public IObserver { Gtk::Box innerBox_; Gtk::Label labelData_; std::string color_; -}; \ No newline at end of file +}; diff --git a/src/ap/mvc/view/EditorWidget.cpp b/src/ap/mvc/view/EditorWidget.cpp index aea6e51..d9affda 100644 --- a/src/ap/mvc/view/EditorWidget.cpp +++ b/src/ap/mvc/view/EditorWidget.cpp @@ -1,10 +1,10 @@ #include "EditorWidget.h" -#include + EditorWidget::EditorWidget(std::shared_ptr c, const std::string& initData) : Gtk::Box(Gtk::Orientation::VERTICAL), - controller_(c), - innerBox_(Gtk::Orientation::VERTICAL) { + innerBox_(Gtk::Orientation::VERTICAL), + controller_(c) { // Create a beautiful border frame_.set_label("ZONE 1: EDITOR (Input View)"); frame_.set_margin(10); @@ -22,18 +22,14 @@ EditorWidget::EditorWidget(std::shared_ptr c, frame_.set_child(innerBox_); this->append(frame_); // Add a frame to the main Box of this class - controller_ = c; + // MVC logic to help the Controller receive update input from the View - button_.signal_clicked().connect([this]() { - std::cout << "1\n"; - controller_->updateRequest(entry_.get_text()); - std::cout << "2\n"; - }); + button_.signal_clicked().connect( + [this]() { controller_->updateRequest(entry_.get_text()); }); } void EditorWidget::onDataChanged(const std::string& newData) { - // Fix string comparison error or do not thing ? if (entry_.get_text() != Glib::ustring(newData)) { entry_.set_text(newData); } -} \ No newline at end of file +} diff --git a/src/ap/mvc/view/EditorWidget.h b/src/ap/mvc/view/EditorWidget.h index 88c69b9..1f46393 100644 --- a/src/ap/mvc/view/EditorWidget.h +++ b/src/ap/mvc/view/EditorWidget.h @@ -17,4 +17,4 @@ class EditorWidget : public Gtk::Box, public IObserver { Gtk::Button button_; std::shared_ptr controller_; -}; \ No newline at end of file +}; diff --git a/src/ap/simple_ap.cpp b/src/ap/simple_ap.cpp index 9d297cd..110c043 100644 --- a/src/ap/simple_ap.cpp +++ b/src/ap/simple_ap.cpp @@ -87,13 +87,16 @@ class MainWindow : public Gtk::Window { if (text.empty()) return; + // Escape text to prevent Pango markup injection + auto escaped = Glib::Markup::escape_text(text); + // Step 2: Update Monitor A (Hard-coded) directly m_labelMonitorA.set_markup("" + - text + ""); + escaped + ""); // Step 3: Update Monitor B (Hard-coded) directly m_labelMonitorB.set_markup("" + - text + ""); + escaped + ""); std::cout << "Updated directly without Model!" << std::endl; }); } @@ -102,4 +105,4 @@ class MainWindow : public Gtk::Window { int main(int argc, char* argv[]) { auto app = Gtk::Application::create("org.gtkmm.example.nomvc"); return app->make_window_and_run(argc, argv); -} \ No newline at end of file +}