diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f55bf0..597eb0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,10 +10,11 @@ pkg_check_modules(GOBJECT2 REQUIRED gobject-2.0) pkg_check_modules(GTK3 REQUIRED gtk+-3.0) pkg_check_modules(NFC REQUIRED libnfc) pkg_check_modules(SOUP REQUIRED libsoup-2.4) +pkg_check_modules(JSON REQUIRED json-glib-1.0) -INCLUDE_DIRECTORIES (${GLIB2_INCLUDE_DIRS} ${GOBJECT2_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${NFC_INCLUDE_DIRS} ${SOUP_INCLUDE_DIRS}) -LINK_DIRECTORIES (${GLIB2_LIBRARY_DIRS} ${GOBJECT2_LIBRARY_DIRS} ${GTK3_LIBRARY_DIRS} ${NFC_LIBRARY_DIRS} ${SOUP_LIBRARY_DIRS}) -add_definitions(${GLIB2_CFLAGS_OTHER} ${GOBJECT2_CFLAGS_OTHER} ${GTK3_CFLAGS_OTHER} ${NFC_CFLAGS_OTHER} ${SOUP_CFLAGS_OTHER}) +INCLUDE_DIRECTORIES (${GLIB2_INCLUDE_DIRS} ${GOBJECT2_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${NFC_INCLUDE_DIRS} ${SOUP_INCLUDE_DIRS} ${JSON_INCLUDE_DIRS}) +LINK_DIRECTORIES (${GLIB2_LIBRARY_DIRS} ${GOBJECT2_LIBRARY_DIRS} ${GTK3_LIBRARY_DIRS} ${NFC_LIBRARY_DIRS} ${SOUP_LIBRARY_DIRS} ${JSON_LIBRARY_DIRS}) +add_definitions(${GLIB2_CFLAGS_OTHER} ${GOBJECT2_CFLAGS_OTHER} ${GTK3_CFLAGS_OTHER} ${NFC_CFLAGS_OTHER} ${SOUP_CFLAGS_OTHER} ${JSON_CFLAGS_OTHER}) add_custom_target(glib-resources DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/resources.c) add_custom_command(DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/glade/*.glade "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.gresource.xml" @@ -25,6 +26,6 @@ aux_source_directory(./src SRC_LIST) add_executable(${PROJECT_NAME} ${SRC_LIST} "${CMAKE_CURRENT_BINARY_DIR}/resources.c" "${HEADERS}") add_dependencies(${PROJECT_NAME} glib-resources) SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/resources.c PROPERTIES GENERATED 1) -target_link_libraries(${PROJECT_NAME} ${GTK3_LIBRARIES} ${NFC_LIBRARIES} ${SOUP_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} ${GTK3_LIBRARIES} ${NFC_LIBRARIES} ${SOUP_LIBRARIES} ${JSON_LIBRARIES}) install (TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/glade/cartItem.glade b/glade/cartItem.glade index 5f553fe..1b89da1 100644 --- a/glade/cartItem.glade +++ b/glade/cartItem.glade @@ -56,7 +56,7 @@ True False - + True False Title diff --git a/src/cart_item.c b/src/cart_item.c index f06aacb..1b9ed30 100644 --- a/src/cart_item.c +++ b/src/cart_item.c @@ -1,4 +1,34 @@ #include "cart_item.h" +#include + +typedef struct _YacosCartItemPriv { + GtkWidget *label_title; + GtkWidget *label_description; + GtkWidget *label_comment; + GtkWidget *label_id; + + GtkWidget *button_properties; + GtkWidget *button_delete; + + GtkWidget *image; + + GtkStack *stack_image_loader; + + yacos_tag_id tag_id; + + struct api { + gchar *url_base; + + SoupSession *soup_session_meta; + } api; +} YacosCartItemPriv; + +struct _YacosCartItem { + /* Inheritance */ + GtkListBoxRow parent; + /* Custom Elements */ + YacosCartItemPriv priv; +}; G_DEFINE_TYPE(YacosCartItem, yacos_cart_item, GTK_TYPE_LIST_BOX_ROW) @@ -13,11 +43,21 @@ static void yacos_cart_item_constructed(GObject *obj) G_OBJECT_CLASS(yacos_cart_item_parent_class)->constructed(obj); } +static void yacos_cart_item_finalize(GObject *gobject) +{ + YacosCartItem *self = yacos_cart_item_get_instance_private(YACOS_CART_ITEM(gobject)); + + g_free(self->priv.api.url_base); + + G_OBJECT_CLASS(yacos_cart_item_parent_class)->constructed(gobject); +} + static void yacos_cart_item_class_init(YacosCartItemClass *klass) { GObjectClass *oclass = G_OBJECT_CLASS(klass); oclass->dispose = yacos_cart_item_dispose; oclass->constructed = yacos_cart_item_constructed; + oclass->finalize = yacos_cart_item_finalize; } static void yacos_cart_item_init(YacosCartItem *self) @@ -26,9 +66,24 @@ static void yacos_cart_item_init(YacosCartItem *self) GtkWidget *box; builder = gtk_builder_new_from_resource("/net/notsyncing/yacos/glade/cartItem.glade"); box = GTK_WIDGET(gtk_builder_get_object(builder, "cart_item")); - gtk_container_add(GTK_CONTAINER(self), box); - // TODO: Get elements + self->priv.label_id = GTK_WIDGET(gtk_builder_get_object(builder, "label_id")); + self->priv.label_title = GTK_WIDGET(gtk_builder_get_object(builder, "label_title")); + self->priv.label_comment = GTK_WIDGET(gtk_builder_get_object(builder, "label_comment")); + self->priv.label_description = GTK_WIDGET(gtk_builder_get_object(builder, "label_description")); + + self->priv.button_delete = GTK_WIDGET(gtk_builder_get_object(builder, "button_delete")); + self->priv.button_properties = GTK_WIDGET(gtk_builder_get_object(builder, "button_properties")); + + self->priv.image = GTK_WIDGET(gtk_builder_get_object(builder, "image_item")); + + self->priv.stack_image_loader = GTK_STACK(gtk_builder_get_object(builder, "stack_image_loader")); + + self->priv.api.url_base = g_strdup("http://localhost:8080/api.php"); + + self->priv.api.soup_session_meta = soup_session_new(); + + gtk_container_add(GTK_CONTAINER(self), box); g_object_unref(builder); } @@ -37,3 +92,74 @@ GtkWidget *yacos_cart_item_new(void) { return GTK_WIDGET(g_object_new(TYPE_YACOS_CART_ITEM, NULL)); } + +void yacos_cart_item_set_id(YacosCartItem *self, yacos_tag_id tag_id) +{ + gchar *id_str; + + self->priv.tag_id = tag_id; + + id_str = yacos_tag_id_to_str(tag_id); + gtk_label_set_text(GTK_LABEL(self->priv.label_id), id_str); + + g_free(id_str); +} + +static void yacos_cart_item_fetch_meta_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) +{ + YacosCartItem *self = YACOS_CART_ITEM(user_data); + const char *temp; + JsonParser *parser; + JsonReader *reader; + + if (msg->status_code != 200) { + // TODO: Make this somewhat error tolerant + g_error("Received error code %d from server.", msg->status_code); + return; + } + + parser = json_parser_new (); + json_parser_load_from_data (parser, + msg->response_body->data, + msg->response_body->length, + NULL); + + reader = json_reader_new (json_parser_get_root (parser)); + + json_reader_read_member (reader, "title"); + temp = json_reader_get_string_value (reader); + gtk_label_set_text(GTK_LABEL(self->priv.label_title), temp); + json_reader_end_member (reader); + + json_reader_read_member (reader, "description"); + temp = json_reader_get_string_value (reader); + gtk_label_set_text(GTK_LABEL(self->priv.label_description), temp); + json_reader_end_member (reader); + + json_reader_read_member (reader, "comment"); + temp = json_reader_get_string_value (reader); + gtk_label_set_text(GTK_LABEL(self->priv.label_comment), temp); + json_reader_end_member (reader); + + g_object_unref (reader); + g_object_unref (parser); +} + +void yacos_cart_item_fetch_meta(YacosCartItem *self) +{ + SoupMessage *msg; + gchar *url; + gchar *id_str; + + id_str = yacos_tag_id_to_str(self->priv.tag_id); + + url = g_strdup_printf("%s?meta&id=%s", self->priv.api.url_base, id_str); + msg = soup_message_new("GET", url); + g_free(url); + g_free(id_str); + + soup_session_queue_message(self->priv.api.soup_session_meta, + msg, + yacos_cart_item_fetch_meta_cb, + self); +} diff --git a/src/cart_item.h b/src/cart_item.h index fd0ef56..44205f5 100644 --- a/src/cart_item.h +++ b/src/cart_item.h @@ -2,32 +2,20 @@ #define CART_ITEM_H #include +#include +#include "scanner.h" G_BEGIN_DECLS G_DECLARE_FINAL_TYPE(YacosCartItem, yacos_cart_item, YACOS, CART_ITEM, GtkListBoxRow) #define TYPE_YACOS_CART_ITEM (yacos_cart_item_get_type()) -typedef struct _YacosCartItemPriv { - GtkLabel label_title; - GtkLabel label_description; - GtkLabel label_comment; - GtkLabel label_id; - GtkButton button_properties; - GtkButton button_delete; - - GtkImage image; -} YacosCartItemPriv; - -struct _YacosCartItem { - /* Inheritance */ - GtkListBoxRow parent; - /* Custom Elements */ - YacosCartItemPriv priv; -}; GtkWidget *yacos_cart_item_new(void); +void yacos_cart_item_set_id(YacosCartItem *self, yacos_tag_id tag_id); +void yacos_cart_item_fetch_meta(YacosCartItem *self); +void yacos_cart_item_fetch_image(YacosCartItem *self); G_END_DECLS diff --git a/src/main.c b/src/main.c index 01261fa..6240174 100644 --- a/src/main.c +++ b/src/main.c @@ -2,22 +2,10 @@ #include "main_window.h" #include "scanner.h" -// TODO: For testing only -#include "cart_item.h" - struct app_state { struct mainWindow *mainWindow; }; -static void newtag(YacosScanner *scanner, struct mainWindow *mainWindow) -{ - // TODO: For testing only - gtk_stack_set_visible_child(mainWindow->stack_main, mainWindow->page_cart.box); - GtkWidget *le = yacos_cart_item_new(); - gtk_list_box_insert(mainWindow->page_cart.list, le, -1); - gtk_widget_show(le); -} - static void activate(GtkApplication* app, gpointer user_data) { struct app_state *app_state = user_data; @@ -40,7 +28,9 @@ static void activate(GtkApplication* app, gpointer user_data) } g_signal_connect(scanner, "newtag", - (GCallback) newtag, (*mainWindow)); + (GCallback) mainWindow_scan_tags, (*mainWindow)); + + mainWindow_scan_tags(scanner, *mainWindow); // TODO: For testing only } diff --git a/src/main_window.c b/src/main_window.c index 457ed81..c758fc0 100644 --- a/src/main_window.c +++ b/src/main_window.c @@ -23,3 +23,14 @@ struct mainWindow *mainWindow_new(GtkApplication *app) return mainWindow; } + +void mainWindow_scan_tags(YacosScanner *scanner, struct mainWindow *mainWindow) +{ + // TODO: For testing only + gtk_stack_set_visible_child(mainWindow->stack_main, mainWindow->page_cart.box); + GtkWidget *le = yacos_cart_item_new(); + yacos_cart_item_set_id(YACOS_CART_ITEM(le), 123); + yacos_cart_item_fetch_meta(YACOS_CART_ITEM(le)); + gtk_list_box_insert(mainWindow->page_cart.list, le, -1); + gtk_widget_show(le); +} diff --git a/src/main_window.h b/src/main_window.h index aa8df61..a2cf9d8 100644 --- a/src/main_window.h +++ b/src/main_window.h @@ -2,6 +2,8 @@ #define MAINWINDOW_H #include +#include "scanner.h" +#include "cart_item.h" struct mainWindow { GtkWidget *main_window; @@ -17,9 +19,10 @@ struct mainWindow { GtkListBox *list; } page_cart; - }; struct mainWindow *mainWindow_new(); +void mainWindow_scan_tags(YacosScanner *scanner, struct mainWindow *mainWindow); + #endif // MAINWINDOW_H diff --git a/src/scanner.c b/src/scanner.c index 88a17bf..a390444 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -152,6 +152,8 @@ static void yacos_scanner_init(YacosScanner *self) { self->detected_tags = NULL; + return; // TODO: Disabled during development + g_debug("Using libnfc %s", nfc_version()); nfc_init(&self->nfc_ctx); if (!self->nfc_ctx) { @@ -171,3 +173,9 @@ YacosScanner *yacos_scanner_new(void) { return g_object_new(YACOS_TYPE_SCANNER, 0); } + +// Free afterwards using g_free +gchar *yacos_tag_id_to_str(yacos_tag_id tag_id) +{ + return g_strdup_printf("%d", tag_id); +} diff --git a/src/scanner.h b/src/scanner.h index efb2fa1..241db1d 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -11,6 +11,8 @@ G_DECLARE_FINAL_TYPE(YacosScanner, yacos_scanner, YACOS, SCANNER, GObject) YacosScanner *yacos_scanner_new(void); +typedef uint32_t yacos_tag_id; + enum YACOS_SCANNER_TAG_TYPE { TAG_TYPE_NONE = 0, TAG_TYPE_ITEM, @@ -18,10 +20,12 @@ enum YACOS_SCANNER_TAG_TYPE { }; struct yacos_scanner_tag { - uint32_t tag_id; // TODO: Maybe make this a uint64 + yacos_tag_id tag_id; // TODO: Maybe make this a uint64 enum YACOS_SCANNER_TAG_TYPE tag_type; }; +gchar *yacos_tag_id_to_str(yacos_tag_id tag_id); + G_END_DECLS #endif // SCANNER_H