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:
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