Compare commits
No commits in common. "2d2d5032c0ffaf7368aa55e168f96a48e1fab1a3" and "28b18aa67b1e1cc1a2e9488a14eee782ba5d100d" have entirely different histories.
2d2d5032c0
...
28b18aa67b
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,2 @@
|
|||||||
.idea/
|
.idea/
|
||||||
.vscode/
|
|
||||||
cmake-build-*
|
cmake-build-*
|
||||||
build/
|
|
||||||
|
|||||||
10
App.cpp
10
App.cpp
@ -1,10 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 01.10.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "App.h"
|
|
||||||
|
|
||||||
App &App::instance() {
|
|
||||||
static App app("pro.aliencat.autocat");
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
17
App.h
17
App.h
@ -1,17 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 01.10.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_APP_H
|
|
||||||
#define AUTOCAT_GNOME_APP_H
|
|
||||||
|
|
||||||
#include "gtkpp/Application.h"
|
|
||||||
|
|
||||||
class App: public gtkpp::Application {
|
|
||||||
public:
|
|
||||||
using gtkpp::Application::Application;
|
|
||||||
static App& instance();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_APP_H
|
|
||||||
@ -1,28 +1,17 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(autocat_gnome)
|
project(autocat_gnome)
|
||||||
include(ExternalProject)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines")
|
||||||
|
|
||||||
#if(APPLE)
|
|
||||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-coroutines-ts")
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g -Og")
|
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g -Og")
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/libsoup@2/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig")
|
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/libsoup@2/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig")
|
||||||
set(OPENSSL_ROOT_DIR /usr/local/opt/openssl)
|
|
||||||
set(OPENSSL_LIBRARIES /usr/local/opt/openssl/lib)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
find_package(nlohmann_json REQUIRED)
|
find_package(nlohmann_json REQUIRED)
|
||||||
find_package(concurrencpp REQUIRED)
|
find_package(folly REQUIRED)
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
find_package(SQLite3 REQUIRED)
|
|
||||||
find_package(fmt REQUIRED)
|
|
||||||
|
|
||||||
pkg_check_modules(GTK REQUIRED gtk4)
|
pkg_check_modules(GTK REQUIRED gtk4)
|
||||||
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||||
@ -75,17 +64,7 @@ add_executable(autocat_gnome main.cpp
|
|||||||
gtkpp/MessageDialog.cpp
|
gtkpp/MessageDialog.cpp
|
||||||
gtkpp/MessageDialog.h
|
gtkpp/MessageDialog.h
|
||||||
gtkpp/Leaflet.cpp
|
gtkpp/Leaflet.cpp
|
||||||
gtkpp/Leaflet.h
|
gtkpp/Leaflet.h)
|
||||||
gtkpp/Dialog.cpp
|
|
||||||
gtkpp/Dialog.h
|
|
||||||
gui/AddNumberDialog.cpp
|
|
||||||
gui/AddNumberDialog.h
|
|
||||||
gui/custom/PlateView.h
|
|
||||||
gui/custom/PlateView.c
|
|
||||||
App.cpp
|
|
||||||
App.h
|
|
||||||
models/Vehicle.cpp
|
|
||||||
models/Vehicle.h services/Storage.cpp services/Storage.h models/Engine.cpp models/Engine.h services/IDBEntity.h models/JsonOptional.h services/IDBEntity.cpp gtkpp/ScrolledWindow.cpp gtkpp/ScrolledWindow.h gtkpp/ListView.cpp gtkpp/ListView.h gtkpp/SelectionModel.cpp gtkpp/SelectionModel.h gtkpp/ListItemFactory.cpp gtkpp/ListItemFactory.h models/VehiclesListFactory.cpp models/VehiclesListFactory.h gtkpp/Separator.cpp gtkpp/Separator.h gtkpp/Label.cpp gtkpp/Label.h)
|
|
||||||
|
|
||||||
target_link_libraries(autocat_gnome ${GTK_LIBRARIES}
|
target_link_libraries(autocat_gnome ${GTK_LIBRARIES}
|
||||||
${GLIB_LIBRARIES}
|
${GLIB_LIBRARIES}
|
||||||
@ -93,10 +72,7 @@ target_link_libraries(autocat_gnome ${GTK_LIBRARIES}
|
|||||||
${LIBADWAITA_LIBRARIES}
|
${LIBADWAITA_LIBRARIES}
|
||||||
${LIBSIGCPP_LIBRARIES}
|
${LIBSIGCPP_LIBRARIES}
|
||||||
nlohmann_json::nlohmann_json
|
nlohmann_json::nlohmann_json
|
||||||
concurrencpp::concurrencpp
|
Folly::folly)
|
||||||
Threads::Threads
|
|
||||||
SQLite::SQLite3
|
|
||||||
fmt::fmt)
|
|
||||||
|
|
||||||
set(XML gui/MainWindow.xml)
|
set(XML gui/MainWindow.xml)
|
||||||
|
|
||||||
|
|||||||
15
coro/Coro.h
15
coro/Coro.h
@ -5,26 +5,19 @@
|
|||||||
#ifndef AUTOCAT_GNOME_CORO_H
|
#ifndef AUTOCAT_GNOME_CORO_H
|
||||||
#define AUTOCAT_GNOME_CORO_H
|
#define AUTOCAT_GNOME_CORO_H
|
||||||
|
|
||||||
|
#include <coroutine>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if __cpp_lib_coroutine
|
|
||||||
#include <coroutine>
|
|
||||||
namespace corons = std;
|
|
||||||
#else
|
|
||||||
#include <experimental/coroutine>
|
|
||||||
namespace corons = std::experimental;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
struct corons::coroutine_traits<void, Args...> {
|
struct std::coroutine_traits<void, Args...> {
|
||||||
struct promise_type {
|
struct promise_type {
|
||||||
void get_return_object() noexcept {}
|
void get_return_object() noexcept {}
|
||||||
|
|
||||||
corons::suspend_never initial_suspend() const noexcept {
|
std::suspend_never initial_suspend() const noexcept {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
corons::suspend_never final_suspend() const noexcept {
|
std::suspend_never final_suspend() const noexcept {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,6 @@
|
|||||||
#include "GLibMainContextExecutor.h"
|
#include "GLibMainContextExecutor.h"
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
int callback(void* data) {
|
int callback(void* data) {
|
||||||
auto executor = reinterpret_cast<GLibMainContextExecutor*>(data);
|
auto executor = reinterpret_cast<GLibMainContextExecutor*>(data);
|
||||||
executor->runFront();
|
executor->runFront();
|
||||||
@ -32,4 +30,3 @@ folly::Executor::KeepAlive<GLibMainContextExecutor> GLibMainContextExecutor::ins
|
|||||||
static GLibMainContextExecutor instance;
|
static GLibMainContextExecutor instance;
|
||||||
return folly::getKeepAliveToken(instance);
|
return folly::getKeepAliveToken(instance);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|||||||
@ -5,16 +5,20 @@
|
|||||||
#ifndef AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H
|
#ifndef AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H
|
||||||
#define AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H
|
#define AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H
|
||||||
|
|
||||||
|
#include <folly/Executor.h>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
class GLibMainContextExecutor {
|
class GLibMainContextExecutor: public folly::Executor {
|
||||||
private:
|
private:
|
||||||
//std::queue<folly::Func> _tasks;
|
std::queue<folly::Func> _tasks;
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//~GLibMainContextExecutor() override = default;
|
static folly::Executor::KeepAlive<GLibMainContextExecutor> instance();
|
||||||
|
~GLibMainContextExecutor() override = default;
|
||||||
|
void add(folly::Func func) override;
|
||||||
|
void runFront();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace gtkpp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Application::Application(const std::string &id) {
|
Application::Application(const std::string &id) {
|
||||||
_app = adw_application_new(id.c_str(), G_APPLICATION_DEFAULT_FLAGS);
|
_app = adw_application_new(id.c_str(), G_APPLICATION_FLAGS_NONE);
|
||||||
g_signal_connect(_app, "activate", G_CALLBACK(activateCallback), this);
|
g_signal_connect(_app, "activate", G_CALLBACK(activateCallback), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,22 +4,14 @@
|
|||||||
|
|
||||||
#include "Box.h"
|
#include "Box.h"
|
||||||
|
|
||||||
namespace gtkpp {
|
gtkpp::Box::Box(GtkOrientation orientation, int spacing) : Widget() {
|
||||||
|
_widget = gtk_box_new(orientation, spacing);
|
||||||
Box::Box(GtkWidget *widget): Widget() {
|
}
|
||||||
_widget = widget;
|
|
||||||
}
|
void gtkpp::Box::append(const gtkpp::Widget& widget) {
|
||||||
|
gtk_box_append(GTK_BOX(_widget), widget.gobj());
|
||||||
Box::Box(GtkOrientation orientation, int spacing) : Widget() {
|
}
|
||||||
_widget = gtk_box_new(orientation, spacing);
|
|
||||||
}
|
void gtkpp::Box::append(GtkWidget *widget) {
|
||||||
|
gtk_box_append(GTK_BOX(_widget), widget);
|
||||||
void Box::append(const gtkpp::Widget& widget) {
|
|
||||||
gtk_box_append(GTK_BOX(_widget), widget.gobj());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::append(GtkWidget *widget) {
|
|
||||||
gtk_box_append(GTK_BOX(_widget), widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,9 +11,8 @@
|
|||||||
|
|
||||||
namespace gtkpp {
|
namespace gtkpp {
|
||||||
|
|
||||||
class Box: public Widget {
|
class Box: public Widget{
|
||||||
public:
|
public:
|
||||||
Box(GtkWidget* widget);
|
|
||||||
Box(GtkOrientation orientation, int spacing);
|
Box(GtkOrientation orientation, int spacing);
|
||||||
void append(const Widget& widget);
|
void append(const Widget& widget);
|
||||||
void append(GtkWidget* widget);
|
void append(GtkWidget* widget);
|
||||||
|
|||||||
@ -6,17 +6,22 @@
|
|||||||
|
|
||||||
namespace gtkpp {
|
namespace gtkpp {
|
||||||
|
|
||||||
|
void clickedCallback(GtkButton*, void* data) {
|
||||||
|
auto button = reinterpret_cast<Button*>(data);
|
||||||
|
button->_signalClicked.emit();
|
||||||
|
}
|
||||||
|
|
||||||
Button::Button() : Widget() {
|
Button::Button() : Widget() {
|
||||||
_widget = gtk_button_new();
|
_widget = gtk_button_new();
|
||||||
setupSignals();
|
g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::setTitle(const std::string &title) {
|
void Button::setTitle(const std::string &title) {
|
||||||
gtk_button_set_label(GTK_BUTTON(_widget), title.c_str());
|
gtk_button_set_label(GTK_BUTTON(_widget), title.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::setIconName(const std::string &name) {
|
void Button::onClick(const std::function<void()> &callback) {
|
||||||
gtk_button_set_icon_name(GTK_BUTTON(_widget), name.c_str());
|
_signalClicked.connect(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,15 +7,21 @@
|
|||||||
|
|
||||||
#include "Widget.h"
|
#include "Widget.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sigc++/sigc++.h>
|
||||||
|
|
||||||
namespace gtkpp {
|
namespace gtkpp {
|
||||||
|
|
||||||
class Button: public Widget {
|
class Button: public Widget {
|
||||||
|
private:
|
||||||
|
sigc::signal<void()> _signalClicked;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend void clickedCallback(GtkButton*, void* data);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Widget::Widget;
|
|
||||||
Button();
|
Button();
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
void setIconName(const std::string& name);
|
void onClick(const std::function<void()>& callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,60 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 17.05.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "Dialog.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
void responseCallback(GtkDialog*, GtkResponseType responseId, void* data) {
|
|
||||||
auto dialog = reinterpret_cast<Dialog*>(data);
|
|
||||||
dialog->_response = responseId;
|
|
||||||
dialog->_signalResponse.emit(responseId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Dialog::Dialog(Window* parent) {
|
|
||||||
|
|
||||||
auto flags = static_cast<GtkDialogFlags>(GTK_DIALOG_DESTROY_WITH_PARENT
|
|
||||||
| GTK_DIALOG_MODAL
|
|
||||||
| GTK_DIALOG_USE_HEADER_BAR);
|
|
||||||
|
|
||||||
auto dialog = gtk_dialog_new_with_buttons("Add plate number",
|
|
||||||
parent->gobj(),
|
|
||||||
flags,
|
|
||||||
"OK", GTK_RESPONSE_OK,
|
|
||||||
"Cancel", GTK_RESPONSE_CANCEL,
|
|
||||||
nullptr);
|
|
||||||
_window = GTK_WINDOW(dialog);
|
|
||||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
|
||||||
_responseHandlerId = g_signal_connect (dialog, "response", G_CALLBACK(responseCallback), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dialog::onResponse(const std::function<void(GtkResponseType)> &callback) {
|
|
||||||
_signalResponse.connect(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
cc::result<GtkResponseType> Dialog::responseAsync() {
|
|
||||||
auto promise = std::make_shared<cc::result_promise<GtkResponseType>>();
|
|
||||||
auto result = promise->get_result();
|
|
||||||
|
|
||||||
_signalResponse.connect([promise](GtkResponseType response){
|
|
||||||
promise->set_result(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dialog::~Dialog() {
|
|
||||||
g_signal_handler_disconnect(_window, _responseHandlerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkResponseType Dialog::currentResponse() const {
|
|
||||||
return _response;
|
|
||||||
}
|
|
||||||
|
|
||||||
Box Dialog::contentWidget() const {
|
|
||||||
auto contentArea = gtk_dialog_get_content_area (GTK_DIALOG(_window));
|
|
||||||
return {contentArea};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 17.05.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_DIALOG_H
|
|
||||||
#define AUTOCAT_GNOME_DIALOG_H
|
|
||||||
|
|
||||||
#include "Window.h"
|
|
||||||
#include "Box.h"
|
|
||||||
#include <sigc++/sigc++.h>
|
|
||||||
#include <concurrencpp/concurrencpp.h>
|
|
||||||
|
|
||||||
namespace cc = concurrencpp;
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
class Dialog: public Window {
|
|
||||||
private:
|
|
||||||
GtkResponseType _response = GTK_RESPONSE_NONE;
|
|
||||||
gulong _responseHandlerId;
|
|
||||||
sigc::signal<void(GtkResponseType)> _signalResponse;
|
|
||||||
friend void responseCallback(GtkDialog*, GtkResponseType responseId, void* data);
|
|
||||||
|
|
||||||
public:
|
|
||||||
void onResponse(const std::function<void(GtkResponseType)>& callback);
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Dialog(Window* parent);
|
|
||||||
~Dialog();
|
|
||||||
cc::result<GtkResponseType> responseAsync();
|
|
||||||
GtkResponseType currentResponse() const;
|
|
||||||
Box contentWidget() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_DIALOG_H
|
|
||||||
@ -13,11 +13,7 @@ namespace gtkpp {
|
|||||||
|
|
||||||
Entry::Entry() : Widget() {
|
Entry::Entry() : Widget() {
|
||||||
_widget = gtk_entry_new();
|
_widget = gtk_entry_new();
|
||||||
_changedHandlerId = g_signal_connect(_widget, "changed", G_CALLBACK(changedCallback), this);
|
g_signal_connect(_widget, "changed", G_CALLBACK(changedCallback), this);
|
||||||
}
|
|
||||||
|
|
||||||
Entry::~Entry() {
|
|
||||||
g_signal_handler_disconnect(_widget, _changedHandlerId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entry::setPlaceholder(const std::string &placeholder) {
|
void Entry::setPlaceholder(const std::string &placeholder) {
|
||||||
|
|||||||
@ -13,7 +13,6 @@ namespace gtkpp {
|
|||||||
|
|
||||||
class Entry: public Widget {
|
class Entry: public Widget {
|
||||||
private:
|
private:
|
||||||
gulong _changedHandlerId;
|
|
||||||
sigc::signal<void()> _signalChanged;
|
sigc::signal<void()> _signalChanged;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -21,7 +20,6 @@ namespace gtkpp {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Entry();
|
Entry();
|
||||||
~Entry();
|
|
||||||
void setPlaceholder(const std::string& placeholder);
|
void setPlaceholder(const std::string& placeholder);
|
||||||
void setPurpose(GtkInputPurpose purpose);
|
void setPurpose(GtkInputPurpose purpose);
|
||||||
void setVisibility(bool visibility);
|
void setVisibility(bool visibility);
|
||||||
|
|||||||
@ -18,12 +18,4 @@ namespace gtkpp {
|
|||||||
void HeaderBar::setTitle(const std::string& title) {
|
void HeaderBar::setTitle(const std::string& title) {
|
||||||
adw_header_bar_set_title_widget(ADW_HEADER_BAR(_widget), gtk_label_new(title.c_str()));
|
adw_header_bar_set_title_widget(ADW_HEADER_BAR(_widget), gtk_label_new(title.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeaderBar::showEndButtons(bool show) {
|
|
||||||
adw_header_bar_set_show_end_title_buttons(ADW_HEADER_BAR(_widget), show);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HeaderBar::packStart(const Widget &widget) {
|
|
||||||
adw_header_bar_pack_start(ADW_HEADER_BAR(_widget), widget.gobj());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -15,8 +15,6 @@ namespace gtkpp {
|
|||||||
HeaderBar();
|
HeaderBar();
|
||||||
explicit HeaderBar(const std::string& title);
|
explicit HeaderBar(const std::string& title);
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
void showEndButtons(bool show);
|
|
||||||
void packStart(const Widget& widget);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 18.12.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "Label.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
Label::Label(): Widget() {
|
|
||||||
_widget = gtk_label_new("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Label::setText(const std::string& text) {
|
|
||||||
gtk_label_set_text(GTK_LABEL(_widget), text.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 18.12.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_LABEL_H
|
|
||||||
#define AUTOCAT_GNOME_LABEL_H
|
|
||||||
|
|
||||||
#include "Widget.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
class Label: public Widget {
|
|
||||||
public:
|
|
||||||
Label();
|
|
||||||
using Widget::Widget;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void setText(const std::string& text);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_LABEL_H
|
|
||||||
@ -11,8 +11,8 @@ namespace gtkpp {
|
|||||||
_widget = adw_leaflet_new();
|
_widget = adw_leaflet_new();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Leaflet::append(const Widget& widget) {
|
void Leaflet::append(Widget *widget) {
|
||||||
adw_leaflet_append(ADW_LEAFLET(_widget), widget.gobj());
|
adw_leaflet_append(ADW_LEAFLET(_widget), widget->gobj());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace gtkpp {
|
|||||||
class Leaflet: public Widget {
|
class Leaflet: public Widget {
|
||||||
public:
|
public:
|
||||||
Leaflet();
|
Leaflet();
|
||||||
void append(const Widget& widget);
|
void append(Widget* widget);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "ListItemFactory.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
void setupListItemCallback(GtkListItemFactory* factory, GtkListItem* list_item, void* data) {
|
|
||||||
auto self = reinterpret_cast<ListItemFactory*>(data);
|
|
||||||
auto widget = self->setup();
|
|
||||||
gtk_list_item_set_child(list_item, widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bindListItemCallback(GtkListItemFactory* factory, GtkListItem* list_item, void* data) {
|
|
||||||
auto self = reinterpret_cast<ListItemFactory*>(data);
|
|
||||||
auto widget = gtk_list_item_get_child(list_item);
|
|
||||||
auto item = gtk_list_item_get_item (list_item);
|
|
||||||
self->bind(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
ListItemFactory::ListItemFactory() {
|
|
||||||
_factory = gtk_signal_list_item_factory_new();
|
|
||||||
g_signal_connect(_factory, "setup", G_CALLBACK(setupListItemCallback), this);
|
|
||||||
g_signal_connect(_factory, "bind", G_CALLBACK(bindListItemCallback), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkListItemFactory *ListItemFactory::gobj() const {
|
|
||||||
return _factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_LISTITEMFACTORY_H
|
|
||||||
#define AUTOCAT_GNOME_LISTITEMFACTORY_H
|
|
||||||
|
|
||||||
#include "Widget.h"
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
class ListItemFactory {
|
|
||||||
private:
|
|
||||||
GtkListItemFactory* _factory;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ListItemFactory();
|
|
||||||
[[nodiscard]] GtkListItemFactory* gobj() const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual GtkWidget* setup() = 0;
|
|
||||||
virtual void bind(GtkWidget* widget) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_LISTITEMFACTORY_H
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "ListView.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
ListView::ListView(SelectionModel selectionModel, ListItemFactory* factory) {
|
|
||||||
_widget = gtk_list_view_new(selectionModel.gobj(), factory->gobj());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_LISTVIEW_H
|
|
||||||
#define AUTOCAT_GNOME_LISTVIEW_H
|
|
||||||
|
|
||||||
#include "Widget.h"
|
|
||||||
#include "SelectionModel.h"
|
|
||||||
#include "ListItemFactory.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
class ListView: public Widget {
|
|
||||||
public:
|
|
||||||
ListView(SelectionModel selectionModel, ListItemFactory* factory);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_LISTVIEW_H
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "ScrolledWindow.h"
|
|
||||||
|
|
||||||
#include <gtk/gtkscrolledwindow.h>
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
ScrolledWindow::ScrolledWindow() {
|
|
||||||
_widget = gtk_scrolled_window_new();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_SCROLLEDWINDOW_H
|
|
||||||
#define AUTOCAT_GNOME_SCROLLEDWINDOW_H
|
|
||||||
|
|
||||||
#include "Widget.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
class ScrolledWindow: public Widget {
|
|
||||||
public:
|
|
||||||
ScrolledWindow();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_SCROLLEDWINDOW_H
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "SelectionModel.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
SelectionModel::SelectionModel(gtkpp::Selection selection) {
|
|
||||||
|
|
||||||
const char *array[] = { "one", "two", "three", "four", nullptr };
|
|
||||||
GtkStringList *sl = gtk_string_list_new ((const char * const *) array);
|
|
||||||
|
|
||||||
switch (selection) {
|
|
||||||
case None:
|
|
||||||
_model = GTK_SELECTION_MODEL(gtk_no_selection_new(G_LIST_MODEL(sl)));
|
|
||||||
case Single:
|
|
||||||
_model = GTK_SELECTION_MODEL(gtk_single_selection_new(G_LIST_MODEL(sl)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkSelectionModel *SelectionModel::gobj() const {
|
|
||||||
return _model;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_SELECTIONMODEL_H
|
|
||||||
#define AUTOCAT_GNOME_SELECTIONMODEL_H
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include <gio/glistmodel.h>
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
enum Selection {
|
|
||||||
None,
|
|
||||||
Single
|
|
||||||
};
|
|
||||||
|
|
||||||
class SelectionModel {
|
|
||||||
private:
|
|
||||||
GtkSelectionModel* _model;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit SelectionModel(Selection selection);
|
|
||||||
[[nodiscard]] GtkSelectionModel* gobj() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_SELECTIONMODEL_H
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 15.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "Separator.h"
|
|
||||||
|
|
||||||
gtkpp::Separator::Separator(GtkOrientation orientation) {
|
|
||||||
_widget = gtk_separator_new(orientation);
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 15.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_SEPARATOR_H
|
|
||||||
#define AUTOCAT_GNOME_SEPARATOR_H
|
|
||||||
|
|
||||||
#include "Widget.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
|
||||||
|
|
||||||
class Separator: public Widget {
|
|
||||||
public:
|
|
||||||
explicit Separator(GtkOrientation orientation);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_SEPARATOR_H
|
|
||||||
105
gtkpp/Widget.cpp
105
gtkpp/Widget.cpp
@ -4,78 +4,35 @@
|
|||||||
|
|
||||||
#include "Widget.h"
|
#include "Widget.h"
|
||||||
|
|
||||||
namespace gtkpp {
|
GtkWidget *gtkpp::Widget::gobj() const {
|
||||||
|
return _widget;
|
||||||
void clickedCallback(GtkButton*, void* data) {
|
}
|
||||||
auto widget = reinterpret_cast<Widget*>(data);
|
|
||||||
widget->_signalClicked.emit();
|
void gtkpp::Widget::setMargins(int margin) {
|
||||||
}
|
gtk_widget_set_margin_top(_widget, margin);
|
||||||
|
gtk_widget_set_margin_bottom(_widget, margin);
|
||||||
void Widget::onClick(const std::function<void()> &callback) {
|
gtk_widget_set_margin_start(_widget, margin);
|
||||||
_signalClicked.connect(callback);
|
gtk_widget_set_margin_end(_widget, margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::Widget() {
|
void gtkpp::Widget::setVAlign(GtkAlign align) {
|
||||||
_widget = nullptr;
|
gtk_widget_set_valign(_widget, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::Widget(GtkWidget *widget) {
|
void gtkpp::Widget::setVExpand(bool expand) {
|
||||||
_widget = widget;
|
gtk_widget_set_vexpand(_widget, expand);
|
||||||
//g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
}
|
||||||
}
|
|
||||||
|
void gtkpp::Widget::setHorizontalMargins(int margin) {
|
||||||
Widget::Widget(GtkBuilder *builder, const char *id) {
|
gtk_widget_set_margin_start(_widget, margin);
|
||||||
_widget = GTK_WIDGET(gtk_builder_get_object(builder, id));
|
gtk_widget_set_margin_end(_widget, margin);
|
||||||
g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
}
|
||||||
}
|
|
||||||
|
void gtkpp::Widget::setVerticalMargins(int margin) {
|
||||||
GtkWidget *Widget::gobj() const {
|
gtk_widget_set_margin_top(_widget, margin);
|
||||||
return _widget;
|
gtk_widget_set_margin_bottom(_widget, margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setMargins(int margin) {
|
void gtkpp::Widget::setEnabled(bool enabled) {
|
||||||
gtk_widget_set_margin_top(_widget, margin);
|
gtk_widget_set_sensitive(_widget, enabled);
|
||||||
gtk_widget_set_margin_bottom(_widget, margin);
|
|
||||||
gtk_widget_set_margin_start(_widget, margin);
|
|
||||||
gtk_widget_set_margin_end(_widget, margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setVAlign(GtkAlign align) {
|
|
||||||
gtk_widget_set_valign(_widget, align);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setVExpand(bool expand) {
|
|
||||||
gtk_widget_set_vexpand(_widget, expand);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setHExpand(bool expand) {
|
|
||||||
gtk_widget_set_hexpand(_widget, expand);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setHorizontalMargins(int margin) {
|
|
||||||
gtk_widget_set_margin_start(_widget, margin);
|
|
||||||
gtk_widget_set_margin_end(_widget, margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setVerticalMargins(int margin) {
|
|
||||||
gtk_widget_set_margin_top(_widget, margin);
|
|
||||||
gtk_widget_set_margin_bottom(_widget, margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setEnabled(bool enabled) {
|
|
||||||
gtk_widget_set_sensitive(_widget, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setupSignals() {
|
|
||||||
g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::show() {
|
|
||||||
gtk_widget_show(_widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::hide() {
|
|
||||||
gtk_widget_hide(_widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
#define AUTOCAT_GNOME_WIDGET_H
|
#define AUTOCAT_GNOME_WIDGET_H
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <sigc++/sigc++.h>
|
|
||||||
|
|
||||||
namespace gtkpp {
|
namespace gtkpp {
|
||||||
|
|
||||||
@ -14,32 +13,14 @@ namespace gtkpp {
|
|||||||
protected:
|
protected:
|
||||||
GtkWidget* _widget;
|
GtkWidget* _widget;
|
||||||
|
|
||||||
private:
|
|
||||||
sigc::signal<void()> _signalClicked;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend void clickedCallback(GtkButton*, void* data);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void setupSignals();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void onClick(const std::function<void()>& callback);
|
|
||||||
|
|
||||||
public:
|
|
||||||
Widget();
|
|
||||||
explicit Widget(GtkWidget* widget);
|
|
||||||
Widget(GtkBuilder* builder, const char* id);
|
|
||||||
[[nodiscard]] GtkWidget* gobj() const;
|
[[nodiscard]] GtkWidget* gobj() const;
|
||||||
void setMargins(int margin);
|
void setMargins(int margin);
|
||||||
void setVerticalMargins(int margin);
|
void setVerticalMargins(int margin);
|
||||||
void setHorizontalMargins(int margin);
|
void setHorizontalMargins(int margin);
|
||||||
void setVAlign(GtkAlign align);
|
void setVAlign(GtkAlign align);
|
||||||
void setVExpand(bool expand);
|
void setVExpand(bool expand);
|
||||||
void setHExpand(bool expand);
|
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
void show();
|
|
||||||
void hide();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "../App.h"
|
|
||||||
|
|
||||||
namespace gtkpp {
|
namespace gtkpp {
|
||||||
|
|
||||||
@ -11,31 +10,29 @@ namespace gtkpp {
|
|||||||
return wnd1._window == wnd2._window;
|
return wnd1._window == wnd2._window;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Window() {
|
Window::Window(std::shared_ptr<Application> app, bool isAppWindow) {
|
||||||
_window = nullptr;
|
|
||||||
_builder = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Window::Window(bool isAppWindow): _isAppWindow(isAppWindow) {
|
|
||||||
if(isAppWindow) {
|
if(isAppWindow) {
|
||||||
auto app = GTK_APPLICATION(App::instance().gobj());
|
_window = GTK_WINDOW(adw_application_window_new(GTK_APPLICATION(app->gobj())));
|
||||||
_window = GTK_WINDOW(adw_application_window_new(app));
|
|
||||||
} else {
|
} else {
|
||||||
_window = GTK_WINDOW(adw_window_new());
|
_window = GTK_WINDOW(adw_window_new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_app = app;
|
||||||
_builder = nullptr;
|
_builder = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Window(const char* resourceName, const char* id) {
|
Window::Window(std::shared_ptr<Application> app, const char* resourceName) {
|
||||||
_builder = gtk_builder_new_from_resource(resourceName);
|
_app = app;
|
||||||
_window = GTK_WINDOW(gtk_builder_get_object(_builder, id));
|
// _builder = gtk_builder_new();
|
||||||
}
|
//
|
||||||
|
// GError* error = nullptr;
|
||||||
|
// gtk_builder_add_from_resource(_builder, resourceName, &error);
|
||||||
|
// if(error) {
|
||||||
|
// throw std::runtime_error(error->message);
|
||||||
|
// }
|
||||||
|
|
||||||
Window::~Window() {
|
_builder = gtk_builder_new_from_resource(resourceName);
|
||||||
if(_window) {
|
_window = GTK_WINDOW(gtk_builder_get_object(_builder, "adw_main_window"));
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::show() {
|
void Window::show() {
|
||||||
@ -54,32 +51,12 @@ namespace gtkpp {
|
|||||||
gtk_window_set_default_size(GTK_WINDOW(_window), width, height);
|
gtk_window_set_default_size(GTK_WINDOW(_window), width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Application> Window::application() const {
|
||||||
|
return _app.lock();
|
||||||
|
}
|
||||||
|
|
||||||
void Window::hide() {
|
void Window::hide() {
|
||||||
gtk_window_close(GTK_WINDOW(_window));
|
gtk_window_close(GTK_WINDOW(_window));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::destroy() {
|
|
||||||
gtk_window_destroy(GTK_WINDOW(_window));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setTransientFor(const Window* window) {
|
|
||||||
gtk_window_set_transient_for(_window, window->gobj());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setModal() {
|
|
||||||
gtk_window_set_modal(_window, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setContent(const Widget& widget) {
|
|
||||||
if(_isAppWindow) {
|
|
||||||
adw_application_window_set_content(ADW_APPLICATION_WINDOW(_window), widget.gobj());
|
|
||||||
} else {
|
|
||||||
adw_window_set_content(ADW_WINDOW(_window), widget.gobj());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::setResizable(bool resizable) {
|
|
||||||
gtk_window_set_resizable(_window, resizable);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,8 +6,6 @@
|
|||||||
#define AUTOCAT_GNOME_WINDOW_H
|
#define AUTOCAT_GNOME_WINDOW_H
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Widget.h"
|
|
||||||
|
|
||||||
#include <adwaita.h>
|
#include <adwaita.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -17,29 +15,22 @@ namespace gtkpp {
|
|||||||
protected:
|
protected:
|
||||||
GtkBuilder* _builder;
|
GtkBuilder* _builder;
|
||||||
GtkWindow* _window;
|
GtkWindow* _window;
|
||||||
bool _isAppWindow;
|
std::weak_ptr<Application> _app;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend bool operator==(const Window& wnd1, const Window& wnd2);
|
friend bool operator==(const Window& wnd1, const Window& wnd2);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Window();
|
Window(std::shared_ptr<Application> app, bool isAppWindow);
|
||||||
explicit Window(bool isAppWindow);
|
Window(std::shared_ptr<Application> app, const char* resourceName);
|
||||||
Window(const char* resourceName, const char* id);
|
|
||||||
virtual ~Window();
|
|
||||||
void show();
|
void show();
|
||||||
void hide();
|
void hide();
|
||||||
void destroy();
|
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
void setDefaultSize(int width, int height);
|
void setDefaultSize(int width, int height);
|
||||||
void setTransientFor(const Window* window);
|
|
||||||
void setModal();
|
|
||||||
[[nodiscard]] GtkWindow* gobj() const;
|
[[nodiscard]] GtkWindow* gobj() const;
|
||||||
void setContent(const Widget& widget);
|
[[nodiscard]] std::shared_ptr<Application> application() const;
|
||||||
void setResizable(bool resizable);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using WindowPtr = std::shared_ptr<Window>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_WINDOW_H
|
#endif //AUTOCAT_GNOME_WINDOW_H
|
||||||
|
|||||||
@ -1,35 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 17.05.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "AddNumberDialog.h"
|
|
||||||
#include "../services/Api.h"
|
|
||||||
#include "../services/Storage.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
AddNumberDialog::AddNumberDialog(gtkpp::Window* parent): gtkpp::Dialog(parent) {
|
|
||||||
auto content = contentWidget();
|
|
||||||
_entry.setMargins(16);
|
|
||||||
_entry.setPlaceholder("Plate number");
|
|
||||||
content.append(_entry);
|
|
||||||
content.append(_spinner);
|
|
||||||
_spinner.setMargins(16);
|
|
||||||
_spinner.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string AddNumberDialog::text() const {
|
|
||||||
return _entry.text();
|
|
||||||
}
|
|
||||||
|
|
||||||
cc::result<void> AddNumberDialog::checkNumber() {
|
|
||||||
_spinner.show();
|
|
||||||
_spinner.start();
|
|
||||||
std::string text = _entry.text();
|
|
||||||
std::transform(text.begin(), text.end(), text.begin(), [](unsigned char c){ return std::toupper(c); });
|
|
||||||
auto vehicle = co_await Api::check(text);
|
|
||||||
Storage::instance().insert(&vehicle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 17.05.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_ADDNUMBERDIALOG_H
|
|
||||||
#define AUTOCAT_GNOME_ADDNUMBERDIALOG_H
|
|
||||||
|
|
||||||
#include "../gtkpp/Dialog.h"
|
|
||||||
#include "../gtkpp/Entry.h"
|
|
||||||
#include "../gtkpp/Spinner.h"
|
|
||||||
|
|
||||||
#include <concurrencpp/concurrencpp.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace cc = concurrencpp;
|
|
||||||
|
|
||||||
class AddNumberDialog: public gtkpp::Dialog {
|
|
||||||
private:
|
|
||||||
gtkpp::Entry _entry;
|
|
||||||
gtkpp::Spinner _spinner;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AddNumberDialog(gtkpp::Window* parent);
|
|
||||||
std::string text() const;
|
|
||||||
cc::result<void> checkNumber();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_ADDNUMBERDIALOG_H
|
|
||||||
@ -5,14 +5,17 @@
|
|||||||
#include "LoginWindow.h"
|
#include "LoginWindow.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "../services/Api.h"
|
#include "../services/Api.h"
|
||||||
|
#include "../coro/GLibMainContextExecutor.h"
|
||||||
|
|
||||||
#include "../gtkpp/HeaderBar.h"
|
#include "../gtkpp/HeaderBar.h"
|
||||||
#include "../gtkpp/MessageDialog.h"
|
#include "../gtkpp/MessageDialog.h"
|
||||||
#include "../App.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <folly/experimental/coro/Task.h>
|
||||||
|
#include <folly/executors/IOThreadPoolExecutor.h>
|
||||||
|
|
||||||
LoginWindow::LoginWindow(): gtkpp::Window(false) {
|
LoginWindow::LoginWindow(std::shared_ptr<gtkpp::Application> app): gtkpp::Window(std::move(app), false) {
|
||||||
|
|
||||||
setDefaultSize(640, 480);
|
setDefaultSize(640, 480);
|
||||||
|
|
||||||
@ -43,7 +46,7 @@ LoginWindow::LoginWindow(): gtkpp::Window(false) {
|
|||||||
rootBox.append(gtkpp::HeaderBar("Login"));
|
rootBox.append(gtkpp::HeaderBar("Login"));
|
||||||
rootBox.append(contentBox);
|
rootBox.append(contentBox);
|
||||||
|
|
||||||
setContent(rootBox);
|
adw_window_set_content(ADW_WINDOW(_window), rootBox.gobj());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoginWindow::loginClicked() {
|
void LoginWindow::loginClicked() {
|
||||||
@ -54,12 +57,14 @@ void LoginWindow::loginClicked() {
|
|||||||
_spinner.start();
|
_spinner.start();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
User user = co_await Api::login(email, password);
|
User user = co_await Api::login(email, password).scheduleOn(GLibMainContextExecutor::instance());
|
||||||
auto mainWindow = std::make_shared<MainWindow>();
|
if(auto app = this->application()) {
|
||||||
mainWindow->show();
|
auto mainWindow = std::make_shared<MainWindow>(app);
|
||||||
App::instance().addWindow(mainWindow);
|
mainWindow->show();
|
||||||
App::instance().removeWindow(this);
|
app->addWindow(mainWindow);
|
||||||
hide();
|
app->removeWindow(this);
|
||||||
|
hide();
|
||||||
|
}
|
||||||
} catch (std::exception& ex) {
|
} catch (std::exception& ex) {
|
||||||
enableControls(true);
|
enableControls(true);
|
||||||
_spinner.stop();
|
_spinner.stop();
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "../gtkpp/Entry.h"
|
#include "../gtkpp/Entry.h"
|
||||||
#include "../gtkpp/Button.h"
|
#include "../gtkpp/Button.h"
|
||||||
#include "../gtkpp/Spinner.h"
|
#include "../gtkpp/Spinner.h"
|
||||||
|
#include "../gtkpp/Application.h"
|
||||||
|
|
||||||
class LoginWindow: public gtkpp::Window {
|
class LoginWindow: public gtkpp::Window {
|
||||||
private:
|
private:
|
||||||
@ -20,7 +21,7 @@ private:
|
|||||||
gtkpp::Spinner _spinner;
|
gtkpp::Spinner _spinner;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LoginWindow();
|
explicit LoginWindow(std::shared_ptr<gtkpp::Application> app);
|
||||||
|
|
||||||
void loginClicked();
|
void loginClicked();
|
||||||
void validateFields();
|
void validateFields();
|
||||||
|
|||||||
@ -3,62 +3,15 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "AddNumberDialog.h"
|
#include "../gtkpp/Box.h"
|
||||||
#include "../gtkpp/MessageDialog.h"
|
|
||||||
#include "../coro/Coro.h"
|
|
||||||
#include "../services/Storage.h"
|
|
||||||
#include "../gtkpp/HeaderBar.h"
|
#include "../gtkpp/HeaderBar.h"
|
||||||
#include "../gtkpp/Separator.h"
|
|
||||||
#include "../gtkpp/SelectionModel.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
MainWindow::MainWindow(std::shared_ptr<gtkpp::Application> app): gtkpp::Window(std::move(app), "/gui/MainWindow.xml") {
|
||||||
|
|
||||||
MainWindow::MainWindow(): gtkpp::Window(true),
|
// gtkpp::Box rootBox(GTK_ORIENTATION_VERTICAL, 0);
|
||||||
_vehiclesListView(gtkpp::SelectionModel(gtkpp::Selection::Single),
|
// rootBox.append(gtkpp::HeaderBar("Main"));
|
||||||
&_vehiclesListFactory) {
|
//
|
||||||
|
// _leaflet.append(&rootBox);
|
||||||
setDefaultSize(640, 480);
|
//
|
||||||
setResizable(true);
|
// adw_application_window_set_content(ADW_APPLICATION_WINDOW(_window), _leaflet.gobj());
|
||||||
|
|
||||||
_addNumberButton.setIconName("list-add-symbolic");
|
|
||||||
_addNumberButton.onClick([this] {
|
|
||||||
showCheckDialog();
|
|
||||||
});
|
|
||||||
|
|
||||||
gtkpp::HeaderBar leftHeader("Vehicles");
|
|
||||||
leftHeader.showEndButtons(false);
|
|
||||||
leftHeader.packStart(_addNumberButton);
|
|
||||||
|
|
||||||
gtkpp::Box leftPanel(GTK_ORIENTATION_VERTICAL, 0);
|
|
||||||
leftPanel.append(leftHeader);
|
|
||||||
leftPanel.append(_vehiclesListView);
|
|
||||||
|
|
||||||
gtkpp::HeaderBar rightHeader;
|
|
||||||
gtkpp::Box rightPanel(GTK_ORIENTATION_VERTICAL, 0);
|
|
||||||
rightPanel.append(rightHeader);
|
|
||||||
rightPanel.setHExpand(true);
|
|
||||||
|
|
||||||
_leaflet.append(leftPanel);
|
|
||||||
_leaflet.append(gtkpp::Separator(GTK_ORIENTATION_VERTICAL));
|
|
||||||
_leaflet.append(rightPanel);
|
|
||||||
_leaflet.setVExpand(true);
|
|
||||||
|
|
||||||
setContent(_leaflet);
|
|
||||||
|
|
||||||
auto vehicles = Storage::instance().select<Vehicle>();
|
|
||||||
std::cout << "" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::showCheckDialog() {
|
|
||||||
AddNumberDialog dialog(this);
|
|
||||||
dialog.show();
|
|
||||||
GtkResponseType response = co_await dialog.responseAsync();
|
|
||||||
|
|
||||||
if(response == GTK_RESPONSE_OK) {
|
|
||||||
try {
|
|
||||||
co_await dialog.checkNumber();
|
|
||||||
} catch(std::exception& ex) {
|
|
||||||
gtkpp::MessageDialog::showError(this, ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,21 +7,13 @@
|
|||||||
|
|
||||||
#include "../gtkpp/Window.h"
|
#include "../gtkpp/Window.h"
|
||||||
#include "../gtkpp/Leaflet.h"
|
#include "../gtkpp/Leaflet.h"
|
||||||
#include "../gtkpp/Button.h"
|
|
||||||
#include "../gtkpp/ListView.h"
|
|
||||||
#include "../models/VehiclesListFactory.h"
|
|
||||||
|
|
||||||
class MainWindow: public gtkpp::Window {
|
class MainWindow: public gtkpp::Window {
|
||||||
private:
|
private:
|
||||||
gtkpp::Leaflet _leaflet;
|
gtkpp::Leaflet _leaflet;
|
||||||
gtkpp::Button _addNumberButton;
|
|
||||||
|
|
||||||
VehiclesListFactory _vehiclesListFactory;
|
|
||||||
gtkpp::ListView _vehiclesListView;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow();
|
explicit MainWindow(std::shared_ptr<gtkpp::Application> app);
|
||||||
void showCheckDialog();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -31,12 +31,6 @@
|
|||||||
</object>
|
</object>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
<child type="start">
|
|
||||||
<object class="GtkButton" id="add_number_button">
|
|
||||||
<property name="icon-name">list-add</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
|
|
||||||
<child type="end">
|
<child type="end">
|
||||||
<object class="GtkMenuButton" id="gtk_btnHeaderHelp">
|
<object class="GtkMenuButton" id="gtk_btnHeaderHelp">
|
||||||
<property name="direction">none</property>
|
<property name="direction">none</property>
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 01.06.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "PlateView.h"
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 01.06.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_PLATEVIEW_H
|
|
||||||
#define AUTOCAT_GNOME_PLATEVIEW_H
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#define PLATEVIEW(obj) GTK_CHECK_CAST(obj, plateview_get_type(), PlateView)
|
|
||||||
#define PLATEVIEW_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, plateview_get_type(), PlateViewClass)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
|
|
||||||
} PlateView;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GtkWidgetClass parent_class;
|
|
||||||
} PlateViewClass;
|
|
||||||
|
|
||||||
guint plateview_get_type (void);
|
|
||||||
GtkWidget* plateview_new (void);
|
|
||||||
void plateview_clear (PlateView* view);
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_PLATEVIEW_H
|
|
||||||
19
main.cpp
19
main.cpp
@ -3,31 +3,32 @@
|
|||||||
#include "services/Settings.h"
|
#include "services/Settings.h"
|
||||||
#include "gtkpp/Application.h"
|
#include "gtkpp/Application.h"
|
||||||
#include "gtkpp/Window.h"
|
#include "gtkpp/Window.h"
|
||||||
#include "App.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <folly/init/Init.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
std::shared_ptr<gtkpp::Window> createMainWindow() {
|
std::shared_ptr<gtkpp::Window> createMainWindow(std::shared_ptr<gtkpp::Application> app) {
|
||||||
auto settings = Settings::instance();
|
auto settings = Settings::instance();
|
||||||
if(settings.user().token.empty()) {
|
if(settings.user().token.empty()) {
|
||||||
return std::make_shared<LoginWindow>();
|
return std::make_shared<LoginWindow>(app);
|
||||||
} else {
|
} else {
|
||||||
return std::make_shared<MainWindow>();
|
return std::make_shared<MainWindow>(app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
folly::init(&argc, &argv);
|
||||||
g_resources_register(g_resource_load("resources.gresource", nullptr));
|
g_resources_register(g_resource_load("resources.gresource", nullptr));
|
||||||
|
|
||||||
auto app = App::instance(); //std::make_shared<gtkpp::Application>("pro.aliencat.autocat");
|
auto app = std::make_shared<gtkpp::Application>("pro.aliencat.autocat");
|
||||||
|
|
||||||
app.onActivate([&](){
|
app->onActivate([&](){
|
||||||
auto window = createMainWindow();
|
auto window = createMainWindow(app);
|
||||||
app.addWindow(window);
|
app->addWindow(window);
|
||||||
window->show();
|
window->show();
|
||||||
});
|
});
|
||||||
|
|
||||||
return app.run(argc, argv);
|
return app->run(argc, argv);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 06.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "Engine.h"
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 06.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_ENGINE_H
|
|
||||||
#define AUTOCAT_GNOME_ENGINE_H
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
class Engine {
|
|
||||||
public:
|
|
||||||
std::string number;
|
|
||||||
int volume;
|
|
||||||
float powerHp;
|
|
||||||
float powerKw;
|
|
||||||
std::string fuelType;
|
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Engine, number, volume, powerHp, powerKw, fuelType)
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_ENGINE_H
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 06.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_JSONOPTIONAL_H
|
|
||||||
#define AUTOCAT_GNOME_JSONOPTIONAL_H
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace nlohmann {
|
|
||||||
|
|
||||||
template<class J, class T>
|
|
||||||
void optional_to_json(J& j, const char* name, const std::optional<T>& value)
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
j[name] = *value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class J, class T>
|
|
||||||
void optional_from_json(const J& j, const char* name, std::optional<T>& value)
|
|
||||||
{
|
|
||||||
const auto it = j.find(name);
|
|
||||||
if (it != j.end())
|
|
||||||
{
|
|
||||||
if(j.at(name).is_null()) {
|
|
||||||
value = std::nullopt;
|
|
||||||
} else {
|
|
||||||
value = it->template get<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename>
|
|
||||||
constexpr bool is_optional = false;
|
|
||||||
template <typename T>
|
|
||||||
constexpr bool is_optional<std::optional<T>> = true;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void extended_to_json(const char *key, nlohmann::json &j, const T &value) {
|
|
||||||
if constexpr (is_optional<T>)
|
|
||||||
optional_to_json(j, key, value);
|
|
||||||
else
|
|
||||||
j[key] = value;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
void extended_from_json(const char *key, const nlohmann::json &j, T &value) {
|
|
||||||
//std::cout << "parsing key " << key << std::endl;
|
|
||||||
if constexpr (is_optional<T>) {
|
|
||||||
optional_from_json(j, key, value);
|
|
||||||
} else {
|
|
||||||
j.at(key).get_to(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EXTEND_JSON_TO(v1) extended_to_json(#v1, nlohmann_json_j, nlohmann_json_t.v1);
|
|
||||||
#define EXTEND_JSON_FROM(v1) extended_from_json(#v1, nlohmann_json_j, nlohmann_json_t.v1);
|
|
||||||
|
|
||||||
#define NLOHMANN_JSONIFY_ALL_THINGS(Type, ...) \
|
|
||||||
friend void to_json(nlohmann::json &nlohmann_json_j, const Type &nlohmann_json_t) { \
|
|
||||||
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_TO, __VA_ARGS__)) \
|
|
||||||
} \
|
|
||||||
friend void from_json(const nlohmann::json &nlohmann_json_j, Type &nlohmann_json_t) { \
|
|
||||||
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_FROM, __VA_ARGS__)) \
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_JSONOPTIONAL_H
|
|
||||||
@ -19,7 +19,6 @@ public:
|
|||||||
public:
|
public:
|
||||||
User() = default;
|
User() = default;
|
||||||
User(const User& user) = default;
|
User(const User& user) = default;
|
||||||
User(User&&) = default;
|
|
||||||
User(std::string_view email, std::string_view token);
|
User(std::string_view email, std::string_view token);
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(User, email, token)
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(User, email, token)
|
||||||
|
|||||||
@ -1,91 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 03.10.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <fmt/core.h>
|
|
||||||
#include "Vehicle.h"
|
|
||||||
|
|
||||||
std::string Vehicle::createTableQuery() {
|
|
||||||
return R"(
|
|
||||||
CREATE TABLE IF NOT EXISTS vehicles(
|
|
||||||
number TEXT NOT NULL PRIMARY KEY,
|
|
||||||
currentNumber TEXT,
|
|
||||||
color TEXT,
|
|
||||||
category TEXT,
|
|
||||||
year INT,
|
|
||||||
addedDate REAL,
|
|
||||||
updatedDate REAL,
|
|
||||||
vin1 TEXT,
|
|
||||||
vin2 TEXT,
|
|
||||||
sts TEXT,
|
|
||||||
pts TEXT,
|
|
||||||
addedBy TEXT,
|
|
||||||
engineNumber TEXT,
|
|
||||||
engineVolume INT,
|
|
||||||
enginePowerHp REAL,
|
|
||||||
enginePowerKw REAL,
|
|
||||||
engineFuelType TEXT
|
|
||||||
);
|
|
||||||
)";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Vehicle::insertQuery() {
|
|
||||||
return fmt::format(R"(
|
|
||||||
INSERT INTO vehicles(number,
|
|
||||||
currentNumber,
|
|
||||||
color,
|
|
||||||
category,
|
|
||||||
year,
|
|
||||||
addedDate,
|
|
||||||
updatedDate,
|
|
||||||
vin1, vin2,
|
|
||||||
sts, pts,
|
|
||||||
addedBy,
|
|
||||||
engineNumber,
|
|
||||||
engineVolume,
|
|
||||||
enginePowerHp,
|
|
||||||
enginePowerKw,
|
|
||||||
engineFuelType)
|
|
||||||
VALUES('{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}')
|
|
||||||
)",
|
|
||||||
number,
|
|
||||||
currentNumber,
|
|
||||||
color.value_or("NULL"),
|
|
||||||
category,
|
|
||||||
year,
|
|
||||||
addedDate,
|
|
||||||
updatedDate,
|
|
||||||
vin1,
|
|
||||||
vin2.value_or("NULL"),
|
|
||||||
sts, pts,
|
|
||||||
addedBy,
|
|
||||||
engine.number,
|
|
||||||
engine.volume,
|
|
||||||
engine.powerHp,
|
|
||||||
engine.powerKw,
|
|
||||||
engine.fuelType);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Vehicle::selectQuery() {
|
|
||||||
return "SELECT * FROM vehicles";
|
|
||||||
}
|
|
||||||
|
|
||||||
Vehicle::Vehicle(sqlite3_stmt *stmt) {
|
|
||||||
number = readString(stmt, 0);
|
|
||||||
currentNumber = readString(stmt, 1);
|
|
||||||
color = readStringOptional(stmt, 2);
|
|
||||||
category = readString(stmt, 3);
|
|
||||||
year = readInt(stmt, 4);
|
|
||||||
addedDate = readDouble(stmt, 5);
|
|
||||||
updatedDate = readDouble(stmt, 6);
|
|
||||||
vin1 = readString(stmt, 7);
|
|
||||||
vin2 = readStringOptional(stmt, 8);
|
|
||||||
sts = readString(stmt, 9);
|
|
||||||
pts = readString(stmt, 10);
|
|
||||||
addedBy = readString(stmt, 11);
|
|
||||||
engine.number = readString(stmt, 12);
|
|
||||||
engine.volume = readInt(stmt, 13);
|
|
||||||
engine.powerHp = readDouble(stmt, 14);
|
|
||||||
engine.powerKw = readDouble(stmt, 15);
|
|
||||||
engine.fuelType = readString(stmt, 16);
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 03.10.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_VEHICLE_H
|
|
||||||
#define AUTOCAT_GNOME_VEHICLE_H
|
|
||||||
|
|
||||||
#include "../services/IDBEntity.h"
|
|
||||||
#include "Engine.h"
|
|
||||||
#include "JsonOptional.h"
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <sqlite3.h>
|
|
||||||
|
|
||||||
class Vehicle: public IDBEntity {
|
|
||||||
public:
|
|
||||||
std::string number;
|
|
||||||
std::string currentNumber;
|
|
||||||
std::optional<std::string> color;
|
|
||||||
std::string category;
|
|
||||||
int year;
|
|
||||||
double addedDate;
|
|
||||||
double updatedDate;
|
|
||||||
std::string vin1;
|
|
||||||
std::optional<std::string> vin2;
|
|
||||||
std::string sts;
|
|
||||||
std::string pts;
|
|
||||||
std::string addedBy;
|
|
||||||
Engine engine;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Vehicle() = default;
|
|
||||||
explicit Vehicle(sqlite3_stmt* stmt);
|
|
||||||
static std::string createTableQuery();
|
|
||||||
static std::string selectQuery();
|
|
||||||
std::string insertQuery() override;
|
|
||||||
|
|
||||||
NLOHMANN_JSONIFY_ALL_THINGS(Vehicle, number, currentNumber, color, category, year, addedDate, updatedDate, vin1, vin2, sts, pts, addedBy, engine)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_VEHICLE_H
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "VehiclesListFactory.h"
|
|
||||||
#include "../gtkpp/Label.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
VehiclesListFactory::VehiclesListFactory() {
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget* VehiclesListFactory::setup() {
|
|
||||||
gtkpp::Label label;
|
|
||||||
return label.gobj();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VehiclesListFactory::bind(GtkWidget *widget) {
|
|
||||||
gtkpp::Label label(widget);
|
|
||||||
label.setText("qwe");
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 13.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_VEHICLESLISTFACTORY_H
|
|
||||||
#define AUTOCAT_GNOME_VEHICLESLISTFACTORY_H
|
|
||||||
|
|
||||||
#include "../gtkpp/ListItemFactory.h"
|
|
||||||
|
|
||||||
class VehiclesListFactory: public gtkpp::ListItemFactory {
|
|
||||||
public:
|
|
||||||
VehiclesListFactory();
|
|
||||||
|
|
||||||
public:
|
|
||||||
GtkWidget* setup() override;
|
|
||||||
void bind(GtkWidget* widget) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_VEHICLESLISTFACTORY_H
|
|
||||||
@ -5,45 +5,53 @@
|
|||||||
#include "Api.h"
|
#include "Api.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <folly/futures/Promise.h>
|
||||||
|
|
||||||
const std::string Api::_baseUrl = "http://127.0.0.1:3000/"; //"https://vps.aliencat.pro:8443/";
|
template<class...Args>
|
||||||
|
struct Callback {
|
||||||
|
void(*function)(Args..., void*) = nullptr;
|
||||||
|
void* state = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Args, typename Lambda>
|
||||||
|
Callback<Args...> voidify(Lambda&& l) {
|
||||||
|
using Func = typename std::decay<Lambda>::type;
|
||||||
|
auto data = new Func(std::forward<Lambda>(l));
|
||||||
|
return {
|
||||||
|
+[](Args... args, void* v)->void {
|
||||||
|
Func* f = static_cast< Func* >(v);
|
||||||
|
(*f)(std::forward<Args>(args)...);
|
||||||
|
delete f;
|
||||||
|
},
|
||||||
|
data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string Api::_baseUrl = "https://vps.aliencat.pro:8443/";
|
||||||
SoupSession* Api::_session = soup_session_new();
|
SoupSession* Api::_session = soup_session_new();
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void callback(SoupSession* session, SoupMessage* message, gpointer userData) {
|
folly::Future<T> Api::post(const std::string &method, const nlohmann::json& params) {
|
||||||
auto promise = reinterpret_cast<cc::result_promise<T>*>(userData);
|
|
||||||
|
|
||||||
if(message->status_code >= 200 && message->status_code < 300) {
|
|
||||||
auto responseString = std::string(message->response_body->data, message->response_body->length);
|
|
||||||
auto json = nlohmann::json::parse(responseString);
|
|
||||||
if(json["success"].get<bool>()) {
|
|
||||||
//std::cout << "response: " << responseString << std::endl;
|
|
||||||
auto data = json["data"].get<T>();
|
|
||||||
promise->set_result(data);
|
|
||||||
} else {
|
|
||||||
auto error = json["error"].get<std::string>();
|
|
||||||
promise->set_exception(std::make_exception_ptr(std::runtime_error(error)));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
promise->set_exception(std::make_exception_ptr(std::runtime_error(message->reason_phrase)));
|
|
||||||
}
|
|
||||||
|
|
||||||
delete promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
cc::result<T> Api::post(const std::string &method, const nlohmann::json& params) {
|
|
||||||
std::string url = _baseUrl + method;
|
std::string url = _baseUrl + method;
|
||||||
auto msg = soup_message_new(SOUP_METHOD_POST, url.c_str());
|
auto msg = soup_message_new(SOUP_METHOD_POST, url.c_str());
|
||||||
|
|
||||||
auto token = Settings::instance().user().token;
|
auto promise = std::make_shared<folly::Promise<T>>();
|
||||||
if(!token.empty()) {
|
auto callback = voidify<SoupSession*, SoupMessage*>([&, promise](SoupSession* session, SoupMessage* message) {
|
||||||
auto authHeader = "Bearer " + token;
|
if(message->status_code >= 200 && message->status_code < 300) {
|
||||||
soup_message_headers_append(msg->request_headers, "Authorization", authHeader.c_str());
|
auto responseString = std::string(message->response_body->data, message->response_body->length);
|
||||||
}
|
auto json = nlohmann::json::parse(responseString);
|
||||||
|
if(json["success"].get<bool>()) {
|
||||||
auto promise = new cc::result_promise<T>();
|
//std::cout << "response: " << responseString << std::endl;
|
||||||
auto result = promise->get_result();
|
auto user = json["data"].get<T>();
|
||||||
|
promise->setValue(user);
|
||||||
|
} else {
|
||||||
|
auto error = json["error"].get<std::string>();
|
||||||
|
promise->setException(std::runtime_error(error));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
promise->setException(std::runtime_error(message->reason_phrase));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
auto jsonStr = params.dump();
|
auto jsonStr = params.dump();
|
||||||
|
|
||||||
@ -52,12 +60,12 @@ cc::result<T> Api::post(const std::string &method, const nlohmann::json& params)
|
|||||||
jsonStr.c_str(),
|
jsonStr.c_str(),
|
||||||
jsonStr.size());
|
jsonStr.size());
|
||||||
|
|
||||||
soup_session_queue_message(_session, msg, callback<T>, promise);
|
soup_session_queue_message(_session, msg, callback.function, callback.state);
|
||||||
|
|
||||||
return result;
|
return promise->getFuture();
|
||||||
}
|
}
|
||||||
|
|
||||||
cc::result<User> Api::login(std::string email, std::string password) {
|
fc::Task<User> Api::login(std::string email, std::string password) {
|
||||||
|
|
||||||
nlohmann::json params = {
|
nlohmann::json params = {
|
||||||
{ "email", email },
|
{ "email", email },
|
||||||
@ -73,12 +81,3 @@ cc::result<User> Api::login(std::string email, std::string password) {
|
|||||||
|
|
||||||
co_return user;
|
co_return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc::result<Vehicle> Api::check(const std::string& number, bool force) {
|
|
||||||
nlohmann::json params = {
|
|
||||||
{ "number", number },
|
|
||||||
{ "forceUpdate", force }
|
|
||||||
};
|
|
||||||
|
|
||||||
return post<Vehicle>("vehicles/check", params);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -8,13 +8,13 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <libsoup/soup.h>
|
#include <libsoup/soup.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <concurrencpp/concurrencpp.h>
|
#include <folly/futures/Future.h>
|
||||||
|
#include <folly/experimental/coro/Task.h>
|
||||||
|
|
||||||
#include "../models/User.h"
|
#include "../models/User.h"
|
||||||
#include "../models/Vehicle.h"
|
|
||||||
#include "../coro/Coro.h"
|
#include "../coro/Coro.h"
|
||||||
|
|
||||||
namespace cc = concurrencpp;
|
namespace fc = folly::coro;
|
||||||
|
|
||||||
class Api {
|
class Api {
|
||||||
private:
|
private:
|
||||||
@ -23,11 +23,10 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static cc::result<T> post(const std::string& method, const nlohmann::json& params);
|
static folly::Future<T> post(const std::string& method, const nlohmann::json& params);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static cc::result<User> login(std::string email, std::string password);
|
static fc::Task<User> login(std::string email, std::string password);
|
||||||
static cc::result<Vehicle> check(const std::string& number, bool force = false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 09.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "IDBEntity.h"
|
|
||||||
|
|
||||||
std::string IDBEntity::readString(sqlite3_stmt *stmt, int column) {
|
|
||||||
return { reinterpret_cast<const char*>(sqlite3_column_text(stmt, column)) };
|
|
||||||
}
|
|
||||||
|
|
||||||
int IDBEntity::readInt(sqlite3_stmt *stmt, int column) {
|
|
||||||
return sqlite3_column_int(stmt, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
double IDBEntity::readDouble(sqlite3_stmt *stmt, int column) {
|
|
||||||
return sqlite3_column_double(stmt, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringOptional IDBEntity::readStringOptional(sqlite3_stmt *stmt, int column) {
|
|
||||||
if(sqlite3_column_type(stmt, column) == SQLITE_NULL) {
|
|
||||||
return std::nullopt;
|
|
||||||
} else {
|
|
||||||
return readString(stmt, column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IntOptional IDBEntity::readIntOptional(sqlite3_stmt *stmt, int column) {
|
|
||||||
if(sqlite3_column_type(stmt, column) == SQLITE_NULL) {
|
|
||||||
return std::nullopt;
|
|
||||||
} else {
|
|
||||||
return readInt(stmt, column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DoubleOptional IDBEntity::readDoubleOptional(sqlite3_stmt *stmt, int column) {
|
|
||||||
if(sqlite3_column_type(stmt, column) == SQLITE_NULL) {
|
|
||||||
return std::nullopt;
|
|
||||||
} else {
|
|
||||||
return readDouble(stmt, column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 06.11.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_IDBENTITY_H
|
|
||||||
#define AUTOCAT_GNOME_IDBENTITY_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <optional>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
#include <sqlite3.h>
|
|
||||||
|
|
||||||
using StringOptional = std::optional<std::string>;
|
|
||||||
using IntOptional = std::optional<int>;
|
|
||||||
using DoubleOptional = std::optional<double>;
|
|
||||||
|
|
||||||
struct IDBEntity {
|
|
||||||
public:
|
|
||||||
virtual std::string insertQuery() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static std::string readString(sqlite3_stmt* stmt, int column);
|
|
||||||
static int readInt(sqlite3_stmt* stmt, int column);
|
|
||||||
static double readDouble(sqlite3_stmt* stmt, int column);
|
|
||||||
static StringOptional readStringOptional(sqlite3_stmt* stmt, int column);
|
|
||||||
static IntOptional readIntOptional(sqlite3_stmt* stmt, int column);
|
|
||||||
static DoubleOptional readDoubleOptional(sqlite3_stmt* stmt, int column);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_IDBENTITY_H
|
|
||||||
@ -9,15 +9,17 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
fs::path Settings::getDataPath() {
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
fs::path getDataPath() {
|
||||||
auto dataDir = std::getenv("XDG_DATA_HOME");
|
auto dataDir = std::getenv("XDG_DATA_HOME");
|
||||||
if(dataDir) {
|
if(dataDir) {
|
||||||
return fs::path(dataDir) / "autocat";
|
return fs::path(dataDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto home = std::getenv("HOME");
|
auto home = std::getenv("HOME");
|
||||||
if(home) {
|
if(home) {
|
||||||
return fs::path(home) / ".local" / "share" / "autocat";
|
return fs::path(home) / ".local" / "share";
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error("Failed to find data home directory");
|
throw std::runtime_error("Failed to find data home directory");
|
||||||
@ -44,7 +46,7 @@ Settings Settings::instance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Settings::Settings() {
|
Settings::Settings() {
|
||||||
_dataPath = getDataPath();
|
_dataPath = getDataPath() / "autocat";
|
||||||
if(!fs::exists(_dataPath)) {
|
if(!fs::exists(_dataPath)) {
|
||||||
fs::create_directories(_dataPath);
|
fs::create_directories(_dataPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,8 +8,6 @@
|
|||||||
#include "../models/User.h"
|
#include "../models/User.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
class Settings {
|
class Settings {
|
||||||
private:
|
private:
|
||||||
std::filesystem::path _dataPath;
|
std::filesystem::path _dataPath;
|
||||||
@ -17,7 +15,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
static Settings instance();
|
static Settings instance();
|
||||||
Settings();
|
Settings();
|
||||||
static fs::path getDataPath();
|
|
||||||
|
|
||||||
[[nodiscard]] User user() const;
|
[[nodiscard]] User user() const;
|
||||||
void setUser(const User& user);
|
void setUser(const User& user);
|
||||||
|
|||||||
@ -1,42 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 25.10.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "Storage.h"
|
|
||||||
#include "Settings.h"
|
|
||||||
|
|
||||||
#include <fmt/core.h>
|
|
||||||
|
|
||||||
Storage Storage::instance() {
|
|
||||||
static Storage instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
Storage::Storage(): _sqlite(nullptr) {
|
|
||||||
auto path = Settings::getDataPath() / "vehicles.sqlite";
|
|
||||||
int result = sqlite3_open(path.c_str(), &_sqlite);
|
|
||||||
if(result != SQLITE_OK) {
|
|
||||||
throw std::runtime_error(sqlite3_errmsg(_sqlite));
|
|
||||||
}
|
|
||||||
|
|
||||||
executeQuery(Vehicle::createTableQuery());
|
|
||||||
}
|
|
||||||
|
|
||||||
Storage::~Storage() {
|
|
||||||
if(_sqlite) {
|
|
||||||
sqlite3_close(_sqlite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Storage::executeQuery(const std::string& query) {
|
|
||||||
char* error = nullptr;
|
|
||||||
sqlite3_exec(_sqlite, query.c_str(), nullptr, nullptr, &error);
|
|
||||||
if(error) {
|
|
||||||
throw std::runtime_error(error);
|
|
||||||
// TODO: error buffer should be deallocated with sqlite3_free()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Storage::insert(IDBEntity *entity) {
|
|
||||||
executeQuery(entity->insertQuery());
|
|
||||||
}
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by selim on 25.10.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AUTOCAT_GNOME_STORAGE_H
|
|
||||||
#define AUTOCAT_GNOME_STORAGE_H
|
|
||||||
|
|
||||||
#include "../models/Vehicle.h"
|
|
||||||
#include "IDBEntity.h"
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
#include <sqlite3.h>
|
|
||||||
|
|
||||||
class Storage {
|
|
||||||
private:
|
|
||||||
sqlite3* _sqlite;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void executeQuery(const std::string& query);
|
|
||||||
|
|
||||||
public:
|
|
||||||
Storage();
|
|
||||||
~Storage();
|
|
||||||
static Storage instance();
|
|
||||||
void insert(IDBEntity* entity);
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::vector<T> select() {
|
|
||||||
auto sql = T::selectQuery();
|
|
||||||
sqlite3_stmt* stmt = nullptr;
|
|
||||||
std::vector<T> rows;
|
|
||||||
|
|
||||||
int result = sqlite3_prepare_v2(_sqlite, sql.c_str(), sql.size(), &stmt, nullptr);
|
|
||||||
if(result != SQLITE_OK) {
|
|
||||||
throw std::runtime_error(sqlite3_errmsg(_sqlite));
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sqlite3_step(stmt);
|
|
||||||
switch(result) {
|
|
||||||
case SQLITE_BUSY:
|
|
||||||
// TODO: Rollback transaction
|
|
||||||
break;
|
|
||||||
case SQLITE_ERROR:
|
|
||||||
throw std::runtime_error(sqlite3_errmsg(_sqlite));
|
|
||||||
case SQLITE_ROW:
|
|
||||||
rows.emplace_back(stmt);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (result == SQLITE_ROW);
|
|
||||||
|
|
||||||
result = sqlite3_finalize(stmt);
|
|
||||||
if(result != SQLITE_OK) {
|
|
||||||
throw std::runtime_error(sqlite3_errmsg(_sqlite));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //AUTOCAT_GNOME_STORAGE_H
|
|
||||||
Loading…
Reference in New Issue
Block a user