kee

Offline IOU signer with QR as transport
git clone https://holbrook.no/src/kee
Info | Log | Files | Refs | README | LICENSE

commit a987217d660e5da50f2626b3e1783dbe66956ee1
parent bf4aae9e5e340ad28d08840c1fec83738cba3100
Author: lash <dev@holbrook.no>
Date:   Sun, 17 Mar 2024 15:39:22 +0000

Reach hacky viewfinder widget for active camera using ui context

Diffstat:
Msrc/gtk/kee-uicontext.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gtk/kee-uicontext.h | 8++++++++
Msrc/gtk/main.c | 3++-
Msrc/gtk/ui.c | 159++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/gtk/ui.h | 5+++--
5 files changed, 196 insertions(+), 73 deletions(-)

diff --git a/src/gtk/kee-uicontext.c b/src/gtk/kee-uicontext.c @@ -5,6 +5,7 @@ #include "ui.h" #include "context.h" #include "state.h" +#include "settings.h" typedef struct { @@ -28,6 +29,8 @@ static guint kee_sigs[KEE_N_SIGS] = {0,}; static void kee_uicontext_set_property(GObject *oo, guint property_id, const GValue *value, GParamSpec *pspec) { KeeUicontext *o = KEE_UICONTEXT(oo); struct ui_container *ui; + GtkWidget *widget; + GtkStack *stack; switch ((enum KEE_PROPS) property_id) { case CORE_CONTEXT: @@ -37,6 +40,7 @@ static void kee_uicontext_set_property(GObject *oo, guint property_id, const GVa ui = g_value_get_pointer(value); o->app = (GApplication*)ui->gapp; o->ctx->front = ui; + o->ui = (struct ui_container*)o->ctx->front; break; case UI_HEADER: ui = (struct ui_container*)o->ctx->front; @@ -47,6 +51,17 @@ static void kee_uicontext_set_property(GObject *oo, guint property_id, const GVa ui->win = g_value_get_object(value); gtk_window_set_titlebar(GTK_WINDOW(ui->win), GTK_WIDGET(ui->head)); break; + case UI_PUSH: + ui = (struct ui_container*)o->ctx->front; + widget = g_value_get_object(value); + stack = GTK_STACK(gtk_window_get_child(GTK_WINDOW(ui->win))); + gtk_stack_set_visible_child(stack, widget); + break; + case CAMERA_VIEW: + ui = (struct ui_container*)o->ctx->front; + widget = g_value_get_object(value); + ui->front_scan = GTK_BOX(widget); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(oo, property_id, pspec); break; @@ -70,6 +85,18 @@ static void kee_uicontext_get_property(GObject *oo, guint property_id, GValue *v ui = (struct ui_container*)o->ctx->front; g_value_set_object(value, ui->front_list); break; + case CAMERA_LIST: + g_value_set_object(value, o->ui->camera_list); + break; + case CAMERA_SCAN: + g_value_set_object(value, o->ui->camera_list); + break; + case CAMERA_DEVICE: + g_value_set_string(value, (char*)settings_get(o->ctx->settings, SETTINGS_VIDEO)); //;o->ui->scan); + break; + case CAMERA_VIEW: + g_value_set_object(value, o->ui->front_scan); //;o->ui->scan); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(oo, property_id, pspec); break; @@ -91,6 +118,18 @@ static void kee_uicontext_class_init(KeeUicontextClass *kls) { NULL ); + kee_sigs[SCAN_CHANGE] = g_signal_newv("scan_change", + G_TYPE_FROM_CLASS(o), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + NULL, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0, + NULL + ); + o->set_property = kee_uicontext_set_property; o->get_property = kee_uicontext_get_property; @@ -104,6 +143,29 @@ static void kee_uicontext_class_init(KeeUicontextClass *kls) { "Ui Container", "UI container to connect", G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); + kee_props[CAMERA_LIST] = g_param_spec_object( + "camera_list", + "Camera device List", + "List model containing current list of available camera", + G_TYPE_LIST_MODEL, + G_PARAM_READABLE); + kee_props[CAMERA_SCAN] = g_param_spec_pointer( + "camera_scan", + "Camera scan", + "Scan context object pointer", + G_PARAM_READABLE); + kee_props[CAMERA_DEVICE] = g_param_spec_string( + "camera_device", + "Camera Device", + "Path for current camera device", + "/dev/video0", + G_PARAM_READABLE); + kee_props[CAMERA_VIEW] = g_param_spec_object( + "camera_view", + "Camera view", + "Viewfinder widget for camera", + GTK_TYPE_BOX, + G_PARAM_READABLE | G_PARAM_WRITABLE); kee_props[UI_HEADER] = g_param_spec_object( "ui_header", "UI header", @@ -122,6 +184,13 @@ static void kee_uicontext_class_init(KeeUicontextClass *kls) { "UI item list", G_TYPE_LIST_MODEL, G_PARAM_READABLE); + kee_props[UI_PUSH] = g_param_spec_object( + "ui_push", + "UI push", + "Add UI element on top of stack", + GTK_TYPE_WIDGET, + G_PARAM_WRITABLE); + kee_props[GAPP] = g_param_spec_pointer( "app", "Gapplication object", @@ -135,11 +204,36 @@ static void kee_uicontext_init(KeeUicontext *self) { //KeeUicontextPrivate *o = kee_uicontext_get_instance_private(self); } +void kee_uicontext_scanchange(KeeUicontext *o, const char *device) { + settings_set(o->ctx->settings, SETTINGS_VIDEO, (unsigned char*)device); + ui_state_change(o->ui, KEE_ST_SCAN_SEARCH, 0); + g_signal_emit(o, kee_sigs[SCAN_WANT], 0); +} + +void kee_uicontext_scanadd(KeeUicontext *o, GtkLabel *label) { + g_list_store_append(G_LIST_STORE(o->ui->camera_list), label); +} + void kee_uicontext_scanstart(KeeUicontext *o) { + GtkWidget *label; + struct kee_camera_devices *camera_device; + if (KEE_IS_SCANNING(o->ui)) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "already in scanning state"); return; } + + camera_device = &o->ctx->camera_devices; + while(1) { + label = gtk_label_new(camera_device->label); + g_object_set_data(G_OBJECT(label), "devpath", camera_device->path); + g_list_store_append(G_LIST_STORE(o->ui->camera_list), GTK_LABEL(label)); + kee_uicontext_scanadd(o, GTK_LABEL(label)); + if (camera_device->next == NULL) { + break; + } + camera_device = camera_device->next; + } ui_state_change(o->ui, KEE_ST_SCAN_SEARCH, 0); g_signal_emit(o, kee_sigs[SCAN_WANT], 0); } diff --git a/src/gtk/kee-uicontext.h b/src/gtk/kee-uicontext.h @@ -13,6 +13,7 @@ typedef struct { enum KEE_SIGS { SCAN_WANT, + SCAN_CHANGE, KEE_N_SIGS, }; @@ -22,6 +23,11 @@ enum KEE_PROPS { UI_HEADER, UI_LIST, UI_WINDOW, + UI_PUSH, + CAMERA_LIST, + CAMERA_SCAN, + CAMERA_DEVICE, + CAMERA_VIEW, GAPP, KEE_N_PROPS, }; @@ -31,6 +37,8 @@ G_DECLARE_FINAL_TYPE(KeeUicontext, kee_uicontext, KEE, UICONTEXT, GObject) KeeUicontext* kee_uicontext_new(void); void kee_uicontext_scanstart(KeeUicontext *o); +void kee_uicontext_scanadd(KeeUicontext *o, GtkLabel *label); +void kee_uicontext_scanchange(KeeUicontext *o, const char *devices); KeeState kee_uicontext_state(KeeUicontext *o); G_END_DECLS diff --git a/src/gtk/main.c b/src/gtk/main.c @@ -48,7 +48,8 @@ int main(int argc, char **argv) { g_signal_connect (ui.gapp, "startup", G_CALLBACK (startup), uctx); g_signal_connect (ui.gapp, "activate", G_CALLBACK (activate), uctx); g_signal_connect (ui.gapp, "shutdown", G_CALLBACK (deactivate), uctx); - g_signal_connect (uctx, "scan_want", G_CALLBACK( ui_handle_scan) , &ctx); + //g_signal_connect (uctx, "scan_want", G_CALLBACK( ui_handle_scan) , &ctx); + g_signal_connect (uctx, "scan_want", G_CALLBACK( ui_handle_scan) , uctx); r = g_application_run (G_APPLICATION (ui.gapp), argc, argv); diff --git a/src/gtk/ui.c b/src/gtk/ui.c @@ -22,6 +22,8 @@ int ui_init(struct ui_container *ui) { } ui->state = 0; ui->front_list = G_LIST_MODEL(gtk_string_list_new(NULL)); + ui->front_scan = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 10)); + ui->camera_list = G_LIST_MODEL(g_list_store_new(GTK_TYPE_LABEL)); return ERR_OK; } @@ -37,18 +39,22 @@ static void ui_handle_unlock_click(GtkWidget *button, gpointer user_data) { //gtk_stack_set_visible_child(ui->stack, GTK_WIDGET(ui->front_view)); } -static void ui_handle_camera_change(GtkDropDown *chooser, GParamSpec *spec, struct kee_context *ctx) { +//static void ui_handle_camera_change(GtkDropDown *chooser, GParamSpec *spec, struct kee_context *ctx) { +static void ui_handle_camera_change(GtkDropDown *chooser, GParamSpec *spec, KeeUicontext *uctx) { GtkLabel *label; char *s; - struct ui_container *ui; + //struct ui_container *ui; - ui = (struct ui_container*)ctx->front; + //ui = (struct ui_container*)ctx->front; label = gtk_drop_down_get_selected_item(chooser); s = g_object_get_data(G_OBJECT(label), "devpath"); g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "dropdown changed: %s -> %s", spec->name, s); - settings_set(ctx->settings, SETTINGS_VIDEO, (unsigned char*)s); - ui_handle_scan(ui->gapp, ctx); + + kee_uicontext_scanchange(uctx, s); + + //ui_handle_scan(ui->gapp, ctx); + //ui_handle_scan(uctx); } @@ -69,53 +75,46 @@ GtkWidget* ui_build_unlock(KeeUicontext *uctx) { return GTK_WIDGET(box); } -static GtkWidget* ui_build_scan_videochooser(struct kee_context *ctx) { +//static GtkWidget* ui_build_scan_videochooser(struct kee_context *ctx) { +static GtkWidget* ui_build_scan_videochooser(KeeUicontext *uctx) { GtkWidget *chooser; - GtkWidget *label; GtkExpression *exp_label; + GListModel *camera_list; //GtkExpression *exp_item; //GClosure *gclosure; - struct kee_camera_devices *camera_device; - struct ui_container *ui; - ui = (struct ui_container*)ctx->front; - ui->camera_list = G_LIST_MODEL(g_list_store_new(GTK_TYPE_LABEL)); + //ui = (struct ui_container*)ctx->front; exp_label = gtk_property_expression_new(GTK_TYPE_LABEL, NULL, "label"); //exp_item = gtk_closure_expression_new(G_TYPE_STRING, gclosure, 1, &exp_label); - chooser = gtk_drop_down_new(G_LIST_MODEL(ui->camera_list), exp_label); - camera_device = &ctx->camera_devices; - while(1) { - label = gtk_label_new(camera_device->label); - g_object_set_data(G_OBJECT(label), "devpath", camera_device->path); - g_list_store_append(G_LIST_STORE(ui->camera_list), GTK_LABEL(label)); - if (camera_device->next == NULL) { - break; - } - camera_device = camera_device->next; - } + g_object_get(uctx, "camera_list", &camera_list, NULL); + chooser = gtk_drop_down_new(camera_list, exp_label); - g_signal_connect(chooser, "notify::selected-item", G_CALLBACK (ui_handle_camera_change), ctx); + + g_signal_connect(chooser, "notify::selected-item", G_CALLBACK (ui_handle_camera_change), uctx); return chooser; } -////static GtkWidget* ui_build_scan(struct ui_container *ui) { -////static GtkWidget* ui_build_scan(struct kee_context *ctx) { -//static GtkWidget* ui_build_scan(KeeUicontext *uctx) { -// GtkWidget *chooser; -// struct ui_container *ui; -// -// ui = (struct ui_container*)ctx->front; -// ui->front_scan = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 10)); -// -// chooser = ui_build_scan_videochooser(ctx); -// gtk_box_append(GTK_BOX(ui->front_scan), chooser); -// -// return GTK_WIDGET(ui->front_scan); -//} -// -// +//static GtkWidget* ui_build_scan(struct ui_container *ui) { +//static GtkWidget* ui_build_scan(struct kee_context *ctx) { +static GtkWidget* ui_build_scan(KeeUicontext *uctx) { + GtkWidget *chooser; + GtkWidget *box; + //struct ui_container *ui; + + //ui = (struct ui_container*)ctx->front; + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10); + + chooser = ui_build_scan_videochooser(uctx); + gtk_box_append(GTK_BOX(box), chooser); + + g_object_set(uctx, "camera_view", box, NULL); + + return GTK_WIDGET(box); +} + + //static GtkWidget* ui_build_view(struct ui_container *ui) { static GtkWidget* ui_build_view(KeeUicontext *uctx) { GtkListItemFactory *factory; @@ -151,8 +150,8 @@ void ui_build(GtkApplication *app, KeeUicontext *uctx) { widget = ui_build_view(uctx); gtk_stack_add_child(GTK_STACK(stack), widget); - //widget = ui_build_scan(uctx); - //gtk_stack_add_child(stack, widget); + widget = ui_build_scan(uctx); + gtk_stack_add_child(GTK_STACK(stack), widget); //g_object_get(uctx, "ui_window", win, NULL); gtk_window_set_child(GTK_WINDOW(win), GTK_WIDGET(stack)); @@ -239,39 +238,59 @@ gboolean ui_scan_code_handler(GstBus *bus, GstMessage *msg, gpointer user_data) return true; } -GtkWidget* ui_build_scan_attach(struct ui_container *ui, const char *device) { +//GtkWidget* ui_build_scan_attach(GtkWidget *front_scan, const char *device) { +// int r; +// struct kee_scanner scan; +// GtkWidget *view; +// +// //scan = &ui->scan; +// scan_init(&scan, device); +// r = scan_begin(&scan); +// if (r) { +// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail scan setup"); +// return NULL; +// } +// view = GTK_WIDGET(scan.video_view); +// gtk_box_append(GTK_BOX(front_scan), view); +// scan_set_handler(&scan, ui_scan_code_handler); +// return view; +//} + +//void ui_handle_scan(GtkApplication *app, struct kee_context *ctx) { +void ui_handle_scan(GtkApplication *app, KeeUicontext *uctx) { int r; - struct kee_scanner *scan; + GtkWidget *front_scan; + struct kee_scanner scan; + char *device; GtkWidget *view; + //struct kee_scanner *scan; - scan = &ui->scan; - scan_init(scan, device); - r = scan_begin(scan); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail scan setup"); - return NULL; - } - view = GTK_WIDGET(scan->video_view); - gtk_box_append(GTK_BOX(ui->front_scan), view); - scan_set_handler(scan, ui_scan_code_handler); - return view; -} + //ui = (struct ui_container*)ctx->front; + //s = settings_get(ctx->settings, SETTINGS_VIDEO); + //scan = &ui->scan; -void ui_handle_scan(GtkApplication *app, struct kee_context *ctx) { - struct ui_container *ui; - unsigned char *s; - struct kee_scanner *scan; - - ui = (struct ui_container*)ctx->front; - s = settings_get(ctx->settings, SETTINGS_VIDEO); - scan = &ui->scan; + g_object_get(uctx, "camera_device", &device, NULL); + //g_object_get(uctx, "camera_scan", &scan, NULL); + g_object_get(uctx, "camera_view", &front_scan, NULL); - if (ui->state & KEE_ST_SCAN_INIT) { - gtk_box_remove(ui->front_scan, GTK_WIDGET(scan->video_view)); - scan_free(scan); - } + //if (ui->state & KEE_ST_SCAN_INIT) { +// if (scan.video_view) { +// gtk_box_remove(GTK_BOX(front_scan), GTK_WIDGET(scan.video_view)); +// scan_free(&scan); +// } - ui_build_scan_attach(ui, (const char*)s); - ui_state_change(ui, KEE_ST_SCAN_INIT, 0); - gtk_stack_set_visible_child(GTK_STACK(ui->stack), GTK_WIDGET(ui->front_scan)); + scan_init(&scan, device); + r = scan_begin(&scan); + if (r) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail scan setup"); + return; + } + view = GTK_WIDGET(scan.video_view); + gtk_box_append(GTK_BOX(front_scan), view); + scan_set_handler(&scan, ui_scan_code_handler); + +// ui_build_scan_attach(uctx, (const char*)s); + //ui_state_change(ui, KEE_ST_SCAN_INIT, 0); + //gtk_stack_set_visible_child(GTK_STACK(ui->stack), GTK_WIDGET(front_scan)); + g_object_set(uctx, "ui_push", GTK_BOX(front_scan), NULL); } diff --git a/src/gtk/ui.h b/src/gtk/ui.h @@ -15,7 +15,7 @@ struct ui_container { GListModel *camera_list; GtkBox *front_scan; GtkHeaderBar *head; - struct kee_scanner scan; + //struct kee_scanner scan; struct kee_context *ctx; int state; }; @@ -26,6 +26,7 @@ void ui_build(GtkApplication *app, KeeUicontext *uctx); int ui_state_change(struct ui_container *ui, int set, int reset); void ui_free(struct ui_container *ui); -void ui_handle_scan(GtkApplication *app, struct kee_context *ctx); +//void ui_handle_scan(GtkApplication *app, struct kee_context *ctx); +void ui_handle_scan(GtkApplication *app, KeeUicontext *uctx); #endif // _UI_H