diff --git a/CMakeLists.txt b/CMakeLists.txt index eea286f..5bbe0ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,16 +15,20 @@ find_package(folly REQUIRED) pkg_check_modules(GTKMM REQUIRED gtkmm-4.0) pkg_check_modules(GLIBMM REQUIRED glibmm-2.68) pkg_check_modules(LIBSOUP REQUIRED libsoup-2.4) -#pkg_check_modules(LIBFOLLY REQUIRED libfolly) -#pkg_check_modules(LIBADWAITA REQUIRED libadwaita-1) +pkg_check_modules(LIBADWAITA REQUIRED libadwaita-1) +pkg_check_modules(LIBSIGCPP REQUIRED sigc++-3.0) include_directories(${GTKMM_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} - ${LIBSOUP_INCLUDE_DIRS}) + ${LIBSOUP_INCLUDE_DIRS} + ${LIBADWAITA_INCLUDE_DIRS} + ${LIBSIGCPP_INCLUDE_DIRS}) link_directories(${GTKMM_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} - ${LIBSOUP_LIBRARY_DIRS}) + ${LIBSOUP_LIBRARY_DIRS} + ${LIBADWAITA_LIBRARY_DIRS} + ${LIBSIGCPP_LIBRARY_DIRS}) add_executable(autocat_gnome main.cpp gui/MainWindow.cpp @@ -39,10 +43,18 @@ add_executable(autocat_gnome main.cpp services/Settings.h gui/TitleBar.cpp gui/TitleBar.h - coro/Coro.h coro/GLibMainContextExecutor.cpp coro/GLibMainContextExecutor.h) + coro/Coro.h + coro/GLibMainContextExecutor.cpp + coro/GLibMainContextExecutor.h + gtkpp/Application.cpp + gtkpp/Application.h + gtkpp/Window.cpp + gtkpp/Window.h) target_link_libraries(autocat_gnome ${GTKMM_LIBRARIES} ${GLIBMM_LIBRARIES} ${LIBSOUP_LIBRARIES} + ${LIBADWAITA_LIBRARIES} + ${LIBSIGCPP_LIBRARIES} nlohmann_json::nlohmann_json Folly::folly) diff --git a/gtkpp/Application.cpp b/gtkpp/Application.cpp new file mode 100644 index 0000000..e007579 --- /dev/null +++ b/gtkpp/Application.cpp @@ -0,0 +1,36 @@ +// +// Created by selim on 10.05.2022. +// + +#include "Application.h" +#include "Window.h" + +namespace gtkpp { + + void activateCallback(GtkApplication* app, void *data) { + auto application = reinterpret_cast(data); + application->_signalActivate.emit(); + } + + Application::Application(const std::string &id) { + _app = adw_application_new(id.c_str(), G_APPLICATION_FLAGS_NONE); + } + + int Application::run(int argc, char **argv) { + return g_application_run(G_APPLICATION(_app), argc, argv); + } + + void Application::onActivate(const std::function& callback) { + g_signal_connect(_app, "activate", G_CALLBACK(activateCallback), this); + _signalActivate.connect(callback); + } + + AdwApplication *Application::gobj() const { + return _app; + } + + void Application::addWindow(const std::shared_ptr& window) { + gtk_application_add_window(GTK_APPLICATION(_app), GTK_WINDOW(window->gobj())); + } + +} diff --git a/gtkpp/Application.h b/gtkpp/Application.h new file mode 100644 index 0000000..adc4f7e --- /dev/null +++ b/gtkpp/Application.h @@ -0,0 +1,35 @@ +// +// Created by selim on 10.05.2022. +// + +#ifndef AUTOCAT_GNOME_APPLICATION_H +#define AUTOCAT_GNOME_APPLICATION_H + +#include +#include +#include +#include + +namespace gtkpp { + + class Window; + + class Application { + private: + AdwApplication* _app; + sigc::signal _signalActivate; + + private: + friend void activateCallback(GtkApplication* app, void* data); + + public: + explicit Application(const std::string& id); + int run(int argc, char* argv[]); + void onActivate(const std::function& callback); + AdwApplication* gobj() const; + void addWindow(const std::shared_ptr& window); + }; + +} + +#endif //AUTOCAT_GNOME_APPLICATION_H diff --git a/gtkpp/Window.cpp b/gtkpp/Window.cpp new file mode 100644 index 0000000..02b7668 --- /dev/null +++ b/gtkpp/Window.cpp @@ -0,0 +1,29 @@ +// +// Created by selim on 10.05.2022. +// + +#include "Window.h" + +gtkpp::Window::Window() { + _window = ADW_WINDOW(adw_window_new()); +} + +gtkpp::Window::Window(std::shared_ptr app) { + _window = ADW_WINDOW(adw_application_window_new(GTK_APPLICATION(app->gobj()))); +} + +void gtkpp::Window::show() { + gtk_window_present(GTK_WINDOW(_window)); +} + +void gtkpp::Window::setTitle(const std::string &title) { + gtk_window_set_title(GTK_WINDOW(_window), title.c_str()); +} + +AdwWindow *gtkpp::Window::gobj() const { + return _window; +} + +void gtkpp::Window::setDefaultSize(int width, int height) { + gtk_window_set_default_size(GTK_WINDOW(_window), width, height); +} diff --git a/gtkpp/Window.h b/gtkpp/Window.h new file mode 100644 index 0000000..d2a38b9 --- /dev/null +++ b/gtkpp/Window.h @@ -0,0 +1,29 @@ +// +// Created by selim on 10.05.2022. +// + +#ifndef AUTOCAT_GNOME_WINDOW_H +#define AUTOCAT_GNOME_WINDOW_H + +#include "Application.h" +#include +#include + +namespace gtkpp { + + class Window { + protected: + AdwWindow* _window; + + public: + Window(); + explicit Window(std::shared_ptr app); + void show(); + void setTitle(const std::string& title); + void setDefaultSize(int width, int height); + AdwWindow* gobj() const; + }; + +} + +#endif //AUTOCAT_GNOME_WINDOW_H diff --git a/gui/LoginWindow.cpp b/gui/LoginWindow.cpp index d82d756..645573a 100644 --- a/gui/LoginWindow.cpp +++ b/gui/LoginWindow.cpp @@ -7,84 +7,117 @@ #include "../services/Api.h" #include "../coro/GLibMainContextExecutor.h" -#include -#include #include #include #include LoginWindow::LoginWindow() { - set_title("Login"); - set_default_size(640, 480); + setDefaultSize(640, 480); - _emailField.set_placeholder_text("Email"); - _passwordField.set_placeholder_text("Password"); - _passwordField.set_input_purpose(Gtk::InputPurpose::PASSWORD); - _passwordField.set_visibility(false); + auto header = adw_header_bar_new(); + adw_header_bar_set_title_widget(ADW_HEADER_BAR(header), gtk_label_new("Login")); - _emailField.signal_changed().connect(sigc::mem_fun(*this, &LoginWindow::validateFields)); - _passwordField.signal_changed().connect(sigc::mem_fun(*this, &LoginWindow::validateFields)); + auto loginField = gtk_entry_new(); + gtk_entry_set_placeholder_text(GTK_ENTRY(loginField), "Email"); + gtk_entry_set_input_purpose(GTK_ENTRY(loginField), GTK_INPUT_PURPOSE_EMAIL); - _loginButton.set_margin_top(8); - _loginButton.set_margin_bottom(8); - _loginButton.set_label("Log in"); - _loginButton.signal_clicked().connect(sigc::mem_fun(*this, &LoginWindow::loginClicked)); - _loginButton.set_sensitive(false); + auto passwordField = gtk_entry_new(); + gtk_entry_set_placeholder_text(GTK_ENTRY(passwordField), "Password"); + gtk_entry_set_input_purpose(GTK_ENTRY(passwordField), GTK_INPUT_PURPOSE_PASSWORD); + gtk_entry_set_visibility(GTK_ENTRY(passwordField), false); - Gtk::Box box(Gtk::Orientation::VERTICAL, 8); - box.set_margin(48); - box.set_valign(Gtk::Align::CENTER); + auto loginButton = gtk_button_new(); + gtk_button_set_label(GTK_BUTTON(loginButton), "Log in"); + gtk_widget_set_margin_top(loginButton, 8); + gtk_widget_set_margin_bottom(loginButton, 8); + gtk_widget_set_sensitive(loginButton, false); - box.append(_emailField); - box.append(_passwordField); - box.append(_loginButton); - box.append(_spinner); + auto spinner = gtk_spinner_new(); - set_child(box); + auto contentBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_box_append(GTK_BOX(contentBox), loginField); + gtk_box_append(GTK_BOX(contentBox), passwordField); + gtk_box_append(GTK_BOX(contentBox), loginButton); + gtk_box_append(GTK_BOX(contentBox), spinner); + gtk_widget_set_margin_start(contentBox, 48); + gtk_widget_set_margin_end(contentBox, 48); + gtk_widget_set_valign(contentBox, GTK_ALIGN_CENTER); + gtk_widget_set_vexpand(contentBox, true); + + auto rootBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_append(GTK_BOX(rootBox), header); + gtk_box_append(GTK_BOX(rootBox), contentBox); + + adw_window_set_content(ADW_WINDOW(_window), rootBox); + +// _emailField.set_placeholder_text("Email"); +// _passwordField.set_placeholder_text("Password"); +// _passwordField.set_input_purpose(Gtk::InputPurpose::PASSWORD); +// _passwordField.set_visibility(false); +// +// _emailField.signal_changed().connect(sigc::mem_fun(*this, &LoginWindow::validateFields)); +// _passwordField.signal_changed().connect(sigc::mem_fun(*this, &LoginWindow::validateFields)); +// +// _loginButton.set_margin_top(8); +// _loginButton.set_margin_bottom(8); +// _loginButton.set_label("Log in"); +// _loginButton.signal_clicked().connect(sigc::mem_fun(*this, &LoginWindow::loginClicked)); +// _loginButton.set_sensitive(false); +// +// Gtk::Box box(Gtk::Orientation::VERTICAL, 8); +// box.set_margin(48); +// box.set_valign(Gtk::Align::CENTER); +// +// box.append(_emailField); +// box.append(_passwordField); +// box.append(_loginButton); +// box.append(_spinner); +// +// set_child(box); } void LoginWindow::loginClicked() { - auto email = _emailField.get_text(); - auto password = _passwordField.get_text(); - - enableControls(false); - _spinner.start(); - - try { - User user = co_await Api::login(email, password).scheduleOn(GLibMainContextExecutor::instance()); - auto app = this->get_application(); - auto mainWindow = new MainWindow(); - mainWindow->show(); - hide(); - app->add_window(*mainWindow); - app->remove_window(*this); - } catch (std::exception& ex) { - enableControls(true); - _spinner.stop(); - showError(ex.what()); - } +// auto email = _emailField.get_text(); +// auto password = _passwordField.get_text(); +// +// enableControls(false); +// _spinner.start(); +// +// try { +// User user = co_await Api::login(email, password).scheduleOn(GLibMainContextExecutor::instance()); +// auto app = this->get_application(); +// auto mainWindow = new MainWindow(); +// mainWindow->show(); +// hide(); +// app->add_window(*mainWindow); +// app->remove_window(*this); +// } catch (std::exception& ex) { +// enableControls(true); +// _spinner.stop(); +// showError(ex.what()); +// } } void LoginWindow::validateFields() { - bool buttonEnabled = _emailField.get_text_length() > 0 && _passwordField.get_text_length() > 0; - _loginButton.set_sensitive(buttonEnabled); +// bool buttonEnabled = _emailField.get_text_length() > 0 && _passwordField.get_text_length() > 0; +// _loginButton.set_sensitive(buttonEnabled); } void LoginWindow::showError(const std::string& message) { - _dialog = std::make_unique("Error", - false, - Gtk::MessageType::ERROR, - Gtk::ButtonsType::OK, - true); - _dialog->set_secondary_text(message); - _dialog->set_transient_for(*this); - _dialog->set_hide_on_close(true); - _dialog->signal_response().connect(sigc::hide(sigc::mem_fun(*_dialog, &Gtk::Widget::hide))); - _dialog->show(); +// _dialog = std::make_unique("Error", +// false, +// Gtk::MessageType::ERROR, +// Gtk::ButtonsType::OK, +// true); +// _dialog->set_secondary_text(message); +// _dialog->set_transient_for(*this); +// _dialog->set_hide_on_close(true); +// _dialog->signal_response().connect(sigc::hide(sigc::mem_fun(*_dialog, &Gtk::Widget::hide))); +// _dialog->show(); } void LoginWindow::enableControls(bool enable) { - _loginButton.set_sensitive(enable); - _emailField.set_sensitive(enable); - _passwordField.set_sensitive(enable); +// _loginButton.set_sensitive(enable); +// _emailField.set_sensitive(enable); +// _passwordField.set_sensitive(enable); } diff --git a/gui/LoginWindow.h b/gui/LoginWindow.h index e690a3b..5f6bdc2 100644 --- a/gui/LoginWindow.h +++ b/gui/LoginWindow.h @@ -5,24 +5,19 @@ #ifndef AUTOCAT_GNOME_LOGINWINDOW_H #define AUTOCAT_GNOME_LOGINWINDOW_H -#include -#include -#include -#include -#include #include +#include "../gtkpp/Window.h" -class LoginWindow: public Gtk::Window { +class LoginWindow: public gtkpp::Window { private: - Gtk::Entry _emailField; - Gtk::Entry _passwordField; - Gtk::Button _loginButton; - Gtk::Spinner _spinner; - std::unique_ptr _dialog; +// Gtk::Entry _emailField; +// Gtk::Entry _passwordField; +// Gtk::Button _loginButton; +// Gtk::Spinner _spinner; +// std::unique_ptr _dialog; public: LoginWindow(); - ~LoginWindow() override = default; void loginClicked(); void validateFields(); diff --git a/main.cpp b/main.cpp index b15da48..4bd8e95 100644 --- a/main.cpp +++ b/main.cpp @@ -1,32 +1,54 @@ #include "gui/MainWindow.h" #include "gui/LoginWindow.h" #include "services/Settings.h" +#include "gtkpp/Application.h" +#include "gtkpp/Window.h" #include #include #include #include #include +#include -std::unique_ptr createStartWindow() { - auto settings = Settings::instance(); - if(settings.user().token.empty()) { - return std::make_unique(); - } else { - return std::make_unique(); - } -} +//std::unique_ptr createStartWindow() { +// auto settings = Settings::instance(); +// if(settings.user().token.empty()) { +// return std::make_unique(); +// } else { +// return std::make_unique(); +// } +//} int main(int argc, char* argv[]) { folly::init(&argc, &argv); - auto app = Gtk::Application::create("pro.aliencat.aliencat"); - auto window = createStartWindow(); +// auto app = Gtk::Application::create("pro.aliencat.aliencat"); +// auto window = createStartWindow(); +// +// app->signal_activate().connect([&](){ +// app->add_window(*window); +// window->show(); +// }); +// return app->run(argc, argv); - app->signal_activate().connect([&](){ - app->add_window(*window); - window->show(); + auto app = std::make_shared("pro.aliencat.autocat"); + + app->onActivate([&](){ + auto settings = Settings::instance(); + + if(settings.user().token.empty()) { + auto window = std::make_shared(); + app->addWindow(window); + window->setTitle("Login"); + window->show(); + } else { + auto window = std::make_unique(app); + window->setTitle("Some title"); + window->show(); + } }); + return app->run(argc, argv); }