Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
gui.cpp
Go to the documentation of this file.
1/**
2 * @file gui.cpp
3 * @brief GUI application for fetching and displaying GitHub user information.
4 *
5 * This file defines a GTK-based graphical user interface that allows users
6 * to input a GitHub username, fetch user information via HTTP, and display it
7 * as formatted JSON. The GUI is styled with embedded CSS.
8 */
9
10#include "user.hpp"
11#include <future>
12#include <gtkmm.h>
13#include <iostream>
14#include <nlohmann/json.hpp>
15#include <sstream>
16#include <thread>
17
18// NOLINTNEXTLINE
19#include "style_css.hpp" // NOLINT
20
21// Path to the CSS file
22/*#ifdef NDEBUG*/
23/* // If in release mode, the CSS is in the build directory*/
24/* const std::string css_file_path = "build/style.css";*/
25/*#else*/
26/* // If in debug mode, the CSS is in the source directory (for
27 * development)*/
28/* const std::string css_file_path = "src/style.css";*/
29/*#endif*/
30
31/**
32 * @class GitHubUserFetcherWindow
33 * @brief Main application window for the GitHub user fetcher GUI.
34 *
35 * This class sets up the UI elements such as the input field, button,
36 * and display area. It fetches user data from GitHub in a background
37 * thread and updates the UI asynchronously using Glib's main loop.
38 */
39class GitHubUserFetcherWindow : public Gtk::Window {
40public:
41 /**
42 * @brief Constructs the main window, sets up widgets and signals.
43 *
44 * Applies CSS styling, initializes all widgets, and connects the button
45 * click signal to the event handler.
46 */
48 auto css_provider = Gtk::CssProvider::create();
49 try {
50 css_provider->load_from_data(css_data);
51 auto display = Gdk::Display::get_default();
52 Gtk::StyleContext::add_provider_for_display(
53 display, css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER);
54 } catch (const Glib::FileError &e) {
55 std::cerr << "Failed to load CSS data: " << e.what() << '\n';
56 } catch (...) {
57 std::cerr << "Unknown error occurred while loading CSS.\n";
58 }
59
60 set_title("GitHub User Fetcher");
61 set_default_size(400, 300);
62
63 box.set_orientation(Gtk::Orientation::VERTICAL);
64 set_child(box);
65
66 entry.set_placeholder_text("Enter GitHub username...");
67 box.append(entry);
68
69 button.set_label("Fetch User");
70 box.append(button);
71
72 scrolled_window.set_child(text_view);
73 scrolled_window.set_policy(Gtk::PolicyType::AUTOMATIC,
74 Gtk::PolicyType::AUTOMATIC);
75 scrolled_window.set_expand(true);
76 box.append(scrolled_window);
77
78 text_view.set_editable(false);
79 text_view.set_wrap_mode(Gtk::WrapMode::WORD);
80
81 button.signal_clicked().connect(
82 sigc::mem_fun(*this, &GitHubUserFetcherWindow::on_button_clicked));
83 }
84
85private:
86 Gtk::Box box; ///< Container for layout
87 Gtk::Entry entry; ///< Text field for GitHub username input
88 Gtk::Button button; ///< Button to trigger fetch
89 Gtk::ScrolledWindow scrolled_window; ///< Scrollable container for text_view
90 Gtk::TextView text_view; ///< Text view to display results or messages
91
92 /**
93 * @brief Event handler for the fetch button.
94 *
95 * Starts a background thread to fetch GitHub user data and updates the
96 * text view with the results. Displays an error message on failure.
97 */
99 std::string username = entry.get_text();
100 if (username.empty()) {
101 show_message("Please enter a username.");
102 return;
103 }
104
105 text_view.get_buffer()->set_text("Fetching...");
106
107 std::thread([this, username]() {
108 try {
109 User user = User::fetch_github_user(username);
110 nlohmann::json json = {{"login", user.login},
111 {"name", user.name},
112 {"company", user.company},
113 {"location", user.location}};
114
115 std::string result = json.dump(4);
116
117 Glib::signal_idle().connect_once(
118 [this, result]() { text_view.get_buffer()->set_text(result); });
119
120 } catch (const std::exception &e) {
121 std::string error_msg = std::string("Error: ") + e.what();
122 Glib::signal_idle().connect_once([this, error_msg]() {
123 text_view.get_buffer()->set_text(error_msg);
124 });
125 }
126 }).detach();
127 }
128
129 /**
130 * @brief Displays a message in the text view area.
131 * @param msg The message to display.
132 */
133 void show_message(const std::string &msg) {
134 text_view.get_buffer()->set_text(msg);
135 }
136};
137
138/**
139 * @brief Application entry point for the GUI.
140 *
141 * Initializes and runs the GTK application, creating a single main window.
142 *
143 * @param argc Argument count.
144 * @param argv Argument vector.
145 * @return Exit code.
146 */
147int main(int argc, char *argv[]) { // NOLINT(cppcoreguidelines-avoid-c-arrays)
148 auto app = Gtk::Application::create("com.example.githubuserfetcher");
149
150 app->signal_activate().connect([&]() {
151 static GitHubUserFetcherWindow window;
152 app->add_window(window);
153 window.present();
154 });
155
156 return app->run(argc, argv);
157}
Main application window for the GitHub user fetcher GUI.
Definition gui.cpp:39
Gtk::TextView text_view
Text view to display results or messages.
Definition gui.cpp:90
Gtk::Box box
Container for layout.
Definition gui.cpp:86
Gtk::Button button
Button to trigger fetch.
Definition gui.cpp:88
void on_button_clicked()
Event handler for the fetch button.
Definition gui.cpp:98
void show_message(const std::string &msg)
Displays a message in the text view area.
Definition gui.cpp:133
Gtk::ScrolledWindow scrolled_window
Scrollable container for text_view.
Definition gui.cpp:89
Gtk::Entry entry
Text field for GitHub username input.
Definition gui.cpp:87
GitHubUserFetcherWindow()
Constructs the main window, sets up widgets and signals.
Definition gui.cpp:47
#define GTK_STYLE_PROVIDER_PRIORITY_USER
int main(void)
Definition sanitycheckc.c:1
Structure representing a GitHub user.
Definition user.h:9
const char * name
Full name.
Definition user.h:11
const char * login
GitHub username.
Definition user.h:10
const char * location
User's location.
Definition user.h:13
const char * company
Company name.
Definition user.h:12