From ff532f5ed98f93cc248e71e22bd333e88455c3cd Mon Sep 17 00:00:00 2001 From: Selim Mustafaev Date: Thu, 12 May 2022 00:35:08 +0300 Subject: [PATCH] another wrappers for GTK widgets --- CMakeLists.txt | 2 +- gtkpp/Application.cpp | 3 +- gtkpp/Box.cpp | 2 +- gtkpp/Button.cpp | 27 +++++++++++++++++ gtkpp/Button.h | 29 ++++++++++++++++++ gtkpp/Entry.cpp | 36 ++++++++++++++++------- gtkpp/Entry.h | 6 ++++ gtkpp/HeaderBar.cpp | 21 +++++++++++++ gtkpp/HeaderBar.h | 22 ++++++++++++++ gtkpp/Spinner.cpp | 13 +++++++++ gtkpp/Spinner.h | 19 ++++++++++++ gtkpp/Widget.cpp | 14 +++++++++ gtkpp/Widget.h | 3 ++ gui/LoginWindow.cpp | 68 +++++++++++++------------------------------ gui/LoginWindow.h | 6 ++-- 15 files changed, 208 insertions(+), 63 deletions(-) create mode 100644 gtkpp/Button.cpp create mode 100644 gtkpp/Button.h create mode 100644 gtkpp/HeaderBar.cpp create mode 100644 gtkpp/HeaderBar.h create mode 100644 gtkpp/Spinner.cpp create mode 100644 gtkpp/Spinner.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cc39cda..f41788b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,7 @@ add_executable(autocat_gnome main.cpp gtkpp/Application.cpp gtkpp/Application.h gtkpp/Window.cpp - gtkpp/Window.h gtkpp/Box.cpp gtkpp/Box.h gtkpp/Widget.cpp gtkpp/Widget.h gtkpp/Entry.cpp gtkpp/Entry.h) + gtkpp/Window.h gtkpp/Box.cpp gtkpp/Box.h gtkpp/Widget.cpp gtkpp/Widget.h gtkpp/Entry.cpp gtkpp/Entry.h gtkpp/Button.cpp gtkpp/Button.h gtkpp/Spinner.cpp gtkpp/Spinner.h gtkpp/HeaderBar.cpp gtkpp/HeaderBar.h) target_link_libraries(autocat_gnome ${GTKMM_LIBRARIES} ${GLIBMM_LIBRARIES} diff --git a/gtkpp/Application.cpp b/gtkpp/Application.cpp index e007579..c25f532 100644 --- a/gtkpp/Application.cpp +++ b/gtkpp/Application.cpp @@ -14,6 +14,7 @@ namespace gtkpp { Application::Application(const std::string &id) { _app = adw_application_new(id.c_str(), G_APPLICATION_FLAGS_NONE); + g_signal_connect(_app, "activate", G_CALLBACK(activateCallback), this); } int Application::run(int argc, char **argv) { @@ -21,7 +22,7 @@ namespace gtkpp { } void Application::onActivate(const std::function& callback) { - g_signal_connect(_app, "activate", G_CALLBACK(activateCallback), this); + _signalActivate.connect(callback); } diff --git a/gtkpp/Box.cpp b/gtkpp/Box.cpp index af791d1..d25b081 100644 --- a/gtkpp/Box.cpp +++ b/gtkpp/Box.cpp @@ -4,7 +4,7 @@ #include "Box.h" -gtkpp::Box::Box(GtkOrientation orientation, int spacing) { +gtkpp::Box::Box(GtkOrientation orientation, int spacing) : Widget() { _widget = gtk_box_new(orientation, spacing); } diff --git a/gtkpp/Button.cpp b/gtkpp/Button.cpp new file mode 100644 index 0000000..db632ae --- /dev/null +++ b/gtkpp/Button.cpp @@ -0,0 +1,27 @@ +// +// Created by selim on 11.05.2022. +// + +#include "Button.h" + +namespace gtkpp { + + void clickedCallback(GtkButton*, void* data) { + auto button = reinterpret_cast(data); + button->_signalClicked.emit(); + } + + Button::Button() : Widget() { + _widget = gtk_button_new(); + g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this); + } + + void Button::setTitle(const std::string &title) { + gtk_button_set_label(GTK_BUTTON(_widget), title.c_str()); + } + + void Button::onClick(const std::function &callback) { + _signalClicked.connect(callback); + } + +} diff --git a/gtkpp/Button.h b/gtkpp/Button.h new file mode 100644 index 0000000..70139ed --- /dev/null +++ b/gtkpp/Button.h @@ -0,0 +1,29 @@ +// +// Created by selim on 11.05.2022. +// + +#ifndef AUTOCAT_GNOME_BUTTON_H +#define AUTOCAT_GNOME_BUTTON_H + +#include "Widget.h" +#include +#include + +namespace gtkpp { + + class Button: public Widget { + private: + sigc::signal _signalClicked; + + private: + friend void clickedCallback(GtkButton*, void* data); + + public: + Button(); + void setTitle(const std::string& title); + void onClick(const std::function& callback); + }; + +} + +#endif //AUTOCAT_GNOME_BUTTON_H diff --git a/gtkpp/Entry.cpp b/gtkpp/Entry.cpp index a79321a..793d1d1 100644 --- a/gtkpp/Entry.cpp +++ b/gtkpp/Entry.cpp @@ -4,18 +4,32 @@ #include "Entry.h" -gtkpp::Entry::Entry() { - _widget = gtk_entry_new(); -} +namespace gtkpp { -void gtkpp::Entry::setPlaceholder(const std::string &placeholder) { - gtk_entry_set_placeholder_text(GTK_ENTRY(_widget), placeholder.c_str()); -} + void changedCallback(GtkEntry* widget, void* data) { + auto entry = reinterpret_cast(data); + entry->_signalChanged.emit(); + } -void gtkpp::Entry::setPurpose(GtkInputPurpose purpose) { - gtk_entry_set_input_purpose(GTK_ENTRY(_widget), purpose); -} + Entry::Entry() : Widget() { + _widget = gtk_entry_new(); + g_signal_connect(_widget, "changed", G_CALLBACK(changedCallback), this); + } + + void Entry::setPlaceholder(const std::string &placeholder) { + gtk_entry_set_placeholder_text(GTK_ENTRY(_widget), placeholder.c_str()); + } + + void Entry::setPurpose(GtkInputPurpose purpose) { + gtk_entry_set_input_purpose(GTK_ENTRY(_widget), purpose); + } + + void Entry::setVisibility(bool visibility) { + gtk_entry_set_visibility(GTK_ENTRY(_widget), visibility); + } + + void Entry::onChanged(const std::function& callback) { + _signalChanged.connect(callback); + } -void gtkpp::Entry::setVisibility(bool visibility) { - gtk_entry_set_visibility(GTK_ENTRY(_widget), visibility); } diff --git a/gtkpp/Entry.h b/gtkpp/Entry.h index 8df3d98..c396b71 100644 --- a/gtkpp/Entry.h +++ b/gtkpp/Entry.h @@ -7,17 +7,23 @@ #include "Widget.h" #include +#include namespace gtkpp { class Entry: public Widget { private: + sigc::signal _signalChanged; + + private: + friend void changedCallback(GtkEntry* widget, void* data); public: Entry(); void setPlaceholder(const std::string& placeholder); void setPurpose(GtkInputPurpose purpose); void setVisibility(bool visibility); + void onChanged(const std::function& callback); }; } diff --git a/gtkpp/HeaderBar.cpp b/gtkpp/HeaderBar.cpp new file mode 100644 index 0000000..c2cafc4 --- /dev/null +++ b/gtkpp/HeaderBar.cpp @@ -0,0 +1,21 @@ +// +// Created by selim on 11.05.2022. +// + +#include "HeaderBar.h" +#include + +namespace gtkpp { + + HeaderBar::HeaderBar() : Widget() { + _widget = adw_header_bar_new(); + } + + HeaderBar::HeaderBar(const std::string &title): HeaderBar() { + setTitle(title); + } + + void HeaderBar::setTitle(const std::string& title) { + adw_header_bar_set_title_widget(ADW_HEADER_BAR(_widget), gtk_label_new(title.c_str())); + } +} \ No newline at end of file diff --git a/gtkpp/HeaderBar.h b/gtkpp/HeaderBar.h new file mode 100644 index 0000000..5ff94a5 --- /dev/null +++ b/gtkpp/HeaderBar.h @@ -0,0 +1,22 @@ +// +// Created by selim on 11.05.2022. +// + +#ifndef AUTOCAT_GNOME_HEADERBAR_H +#define AUTOCAT_GNOME_HEADERBAR_H + +#include "Widget.h" +#include + +namespace gtkpp { + + class HeaderBar: public Widget { + public: + HeaderBar(); + explicit HeaderBar(const std::string& title); + void setTitle(const std::string& title); + }; + +} + +#endif //AUTOCAT_GNOME_HEADERBAR_H diff --git a/gtkpp/Spinner.cpp b/gtkpp/Spinner.cpp new file mode 100644 index 0000000..a3eae51 --- /dev/null +++ b/gtkpp/Spinner.cpp @@ -0,0 +1,13 @@ +// +// Created by selim on 11.05.2022. +// + +#include "Spinner.h" + +namespace gtkpp { + + Spinner::Spinner() : Widget() { + _widget = gtk_spinner_new(); + } + +} diff --git a/gtkpp/Spinner.h b/gtkpp/Spinner.h new file mode 100644 index 0000000..171308f --- /dev/null +++ b/gtkpp/Spinner.h @@ -0,0 +1,19 @@ +// +// Created by selim on 11.05.2022. +// + +#ifndef AUTOCAT_GNOME_SPINNER_H +#define AUTOCAT_GNOME_SPINNER_H + +#include "Widget.h" + +namespace gtkpp { + + class Spinner: public Widget { + public: + Spinner(); + }; + +} + +#endif //AUTOCAT_GNOME_SPINNER_H diff --git a/gtkpp/Widget.cpp b/gtkpp/Widget.cpp index ef7e091..33a213a 100644 --- a/gtkpp/Widget.cpp +++ b/gtkpp/Widget.cpp @@ -22,3 +22,17 @@ void gtkpp::Widget::setVAlign(GtkAlign align) { void gtkpp::Widget::setVExpand(bool expand) { gtk_widget_set_vexpand(_widget, expand); } + +void gtkpp::Widget::setHorizontalMargins(int margin) { + gtk_widget_set_margin_start(_widget, margin); + gtk_widget_set_margin_end(_widget, margin); +} + +void gtkpp::Widget::setVerticalMargins(int margin) { + gtk_widget_set_margin_top(_widget, margin); + gtk_widget_set_margin_bottom(_widget, margin); +} + +void gtkpp::Widget::setEnabled(bool enabled) { + gtk_widget_set_sensitive(_widget, enabled); +} diff --git a/gtkpp/Widget.h b/gtkpp/Widget.h index 79f8124..8615f9c 100644 --- a/gtkpp/Widget.h +++ b/gtkpp/Widget.h @@ -16,8 +16,11 @@ namespace gtkpp { public: [[nodiscard]] GtkWidget* gobj() const; void setMargins(int margin); + void setVerticalMargins(int margin); + void setHorizontalMargins(int margin); void setVAlign(GtkAlign align); void setVExpand(bool expand); + void setEnabled(bool enabled); }; } diff --git a/gui/LoginWindow.cpp b/gui/LoginWindow.cpp index c5bd8e5..8509bac 100644 --- a/gui/LoginWindow.cpp +++ b/gui/LoginWindow.cpp @@ -7,70 +7,44 @@ #include "../services/Api.h" #include "../coro/GLibMainContextExecutor.h" +#include "../gtkpp/HeaderBar.h" + #include #include #include -LoginWindow::LoginWindow(): _rootBox(GTK_ORIENTATION_VERTICAL, 0), - _contentBox(GTK_ORIENTATION_VERTICAL, 8) { +LoginWindow::LoginWindow() { setDefaultSize(640, 480); - auto header = adw_header_bar_new(); - adw_header_bar_set_title_widget(ADW_HEADER_BAR(header), gtk_label_new("Login")); - - 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); - - auto spinner = gtk_spinner_new(); - _loginEntry.setPlaceholder("Email"); _loginEntry.setPurpose(GTK_INPUT_PURPOSE_EMAIL); + _loginEntry.onChanged([this] { validateFields(); }); _passwordEntry.setPlaceholder("Password"); _passwordEntry.setPurpose(GTK_INPUT_PURPOSE_PASSWORD); _passwordEntry.setVisibility(false); + _passwordEntry.onChanged([this] { validateFields(); }); - _contentBox.append(_loginEntry); - _contentBox.append(_passwordEntry); - _contentBox.append(loginButton); - _contentBox.append(spinner); - _contentBox.setMargins(48); - _contentBox.setVAlign(GTK_ALIGN_CENTER); - _contentBox.setVExpand(true); + _loginButton.setTitle("Log in"); + _loginButton.setVerticalMargins(8); + _loginButton.setEnabled(false); + _loginButton.onClick([this] { loginClicked(); }); - _rootBox.append(header); - _rootBox.append(_contentBox); + gtkpp::Box contentBox(GTK_ORIENTATION_VERTICAL, 8); + contentBox.append(_loginEntry); + contentBox.append(_passwordEntry); + contentBox.append(_loginButton); + contentBox.append(_spinner); + contentBox.setMargins(48); + contentBox.setVAlign(GTK_ALIGN_CENTER); + contentBox.setVExpand(true); - adw_window_set_content(ADW_WINDOW(_window), _rootBox.gobj()); + gtkpp::Box rootBox(GTK_ORIENTATION_VERTICAL, 0); + rootBox.append(gtkpp::HeaderBar("Login")); + rootBox.append(contentBox); -// _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); + adw_window_set_content(ADW_WINDOW(_window), rootBox.gobj()); } void LoginWindow::loginClicked() { diff --git a/gui/LoginWindow.h b/gui/LoginWindow.h index bcb67f8..afa46d4 100644 --- a/gui/LoginWindow.h +++ b/gui/LoginWindow.h @@ -9,6 +9,8 @@ #include "../gtkpp/Window.h" #include "../gtkpp/Box.h" #include "../gtkpp/Entry.h" +#include "../gtkpp/Button.h" +#include "../gtkpp/Spinner.h" class LoginWindow: public gtkpp::Window { private: @@ -18,10 +20,10 @@ private: // Gtk::Spinner _spinner; // std::unique_ptr _dialog; - gtkpp::Box _rootBox; - gtkpp::Box _contentBox; gtkpp::Entry _loginEntry; gtkpp::Entry _passwordEntry; + gtkpp::Button _loginButton; + gtkpp::Spinner _spinner; public: LoginWindow();