diff options
-rw-r--r-- | src/uca.c | 60 | ||||
-rw-r--r-- | src/uca.h | 8 | ||||
-rw-r--r-- | test/control.c | 88 | ||||
-rw-r--r-- | test/control.glade | 78 | ||||
-rw-r--r-- | test/enum.c | 8 |
5 files changed, 201 insertions, 41 deletions
@@ -25,31 +25,43 @@ #include "cameras/photron.h" #endif +const char *uca_unit_map[] = { + "px", + "bits", + "ns", + "µs", + "ms", + "s", + "rows", + "fps" + "" +}; + static struct uca_property_t property_map[UCA_PROP_LAST+1] = { - { "name", uca_na, uca_string }, - { "width", uca_pixel, uca_uint32t }, - { "width.min", uca_pixel, uca_uint32t }, - { "width.max", uca_pixel, uca_uint32t }, - { "height", uca_pixel, uca_uint32t }, - { "height.min", uca_pixel, uca_uint32t }, - { "height.max", uca_pixel, uca_uint32t }, - { "offset.x", uca_pixel, uca_uint32t }, - { "offset.y", uca_pixel, uca_uint32t }, - { "bitdepth", uca_bits, uca_uint8t }, - { "exposure", uca_us, uca_uint32t }, - { "exposure.min", uca_ns, uca_uint32t }, - { "exposure.max", uca_ms, uca_uint32t }, - { "delay", uca_us, uca_uint32t }, - { "delay.min", uca_ns, uca_uint32t }, - { "delay.max", uca_ms, uca_uint32t }, - { "framerate", uca_na, uca_uint32t }, - { "triggermode", uca_na, uca_uint32t }, - { "timestampmode", uca_na, uca_uint32t }, - { "scan-mode", uca_na, uca_uint32t }, - { "interlace.samplerate", uca_na, uca_uint32t }, - { "interlace.threshold.pixel", uca_na, uca_uint32t }, - { "interlace.threshold.row", uca_na, uca_uint32t }, - { "correctionmode", uca_na, uca_uint32t }, + { "general.name", uca_na, uca_string }, + { "image.width", uca_pixel, uca_uint32t }, + { "image.width.min", uca_pixel, uca_uint32t }, + { "image.width.max", uca_pixel, uca_uint32t }, + { "image.height", uca_pixel, uca_uint32t }, + { "image.height.min", uca_pixel, uca_uint32t }, + { "image.height.max", uca_pixel, uca_uint32t }, + { "image.offset.x", uca_pixel, uca_uint32t }, + { "image.offset.y", uca_pixel, uca_uint32t }, + { "image.bitdepth", uca_bits, uca_uint8t }, + { "time.exposure", uca_us, uca_uint32t }, + { "time.exposure.min", uca_ns, uca_uint32t }, + { "time.exposure.max", uca_ms, uca_uint32t }, + { "time.delay", uca_us, uca_uint32t }, + { "time.delay.min", uca_ns, uca_uint32t }, + { "time.delay.max", uca_ms, uca_uint32t }, + { "time.framerate", uca_fps, uca_uint32t }, + { "mode.trigger", uca_na, uca_uint32t }, + { "mode.timestamp", uca_na, uca_uint32t }, + { "mode.scan", uca_na, uca_uint32t }, + { "ipe.interlace.samplerate", uca_na, uca_uint32t }, + { "ipe.interlace.threshold.pixel", uca_na, uca_uint32t }, + { "ipe.interlace.threshold.row", uca_na, uca_uint32t }, + { "mode.correction", uca_na, uca_uint32t }, { NULL, 0, 0 } }; @@ -93,6 +93,7 @@ enum uca_property_ids { #define UCA_CORRECT_HOTPIXEL 0x02 #define UCA_CORRECT_GAIN 0x04 + /** * \brief Describe a property used by cameras and frame grabbers */ @@ -100,13 +101,14 @@ struct uca_property_t { const char *name; enum uca_unit { - uca_pixel, + uca_pixel = 0, uca_bits, uca_ns, uca_us, uca_ms, uca_s, uca_rows, + uca_fps, uca_na } unit; @@ -117,10 +119,12 @@ struct uca_property_t { } type; }; +extern const char *uca_unit_map[]; /**< maps unit numbers to corresponding strings */ + enum uca_errors { UCA_NO_ERROR = 0, UCA_ERR_GRABBER_NOT_FOUND, - UCA_ERR_CAM_NOT_FOUND, /**< camera probing or initialization failed */ + UCA_ERR_CAM_NOT_FOUND, /**< camera probing or initialization failed */ UCA_ERR_PROP_INVALID, /**< the requested property is not supported by the camera */ UCA_ERR_PROP_GENERAL, /**< error occured reading/writing the property */ UCA_ERR_PROP_VALUE_OUT_OF_RANGE, /**< error occured writing the property */ diff --git a/test/control.c b/test/control.c index dd71f47..2c08308 100644 --- a/test/control.c +++ b/test/control.c @@ -58,6 +58,76 @@ void *grab_thread(void *args) } } +void get_first_level_root(GtkTreeStore *store, GtkTreeIter *iter, gchar *group) +{ + GtkTreeIter root; + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &root)) { + gchar *str; + gtk_tree_model_get(GTK_TREE_MODEL(store), &root, 0, &str, -1); + if (g_strcmp0(group, str) == 0) { + *iter = root; + return; + } + + /* Iterate through all groups */ + while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &root)) { + gtk_tree_model_get(GTK_TREE_MODEL(store), &root, 0, &str, -1); + if (g_strcmp0(group, str) == 0) { + *iter = root; + g_free(str); + return; + } + } + + /* Not found, append the group */ + g_free(str); + } + + /* Tree is empty or group is not found */ + gtk_tree_store_append(store, iter, NULL); + gtk_tree_store_set(store, iter, 0, group, -1); +} + +void find_recursively(GtkTreeStore *store, GtkTreeIter *root, GtkTreeIter *result, gchar **tokens, int depth) +{ + GtkTreeIter iter; + gchar *str; + gchar *current_token = tokens[depth]; + + if (current_token == NULL) { + *result = *root; + return; + } + + if (!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), root)) { + gtk_tree_store_append(store, &iter, root); + if (tokens[depth+1] == NULL) { + *result = iter; + return; + } + else { + gtk_tree_store_set(store, &iter, 0, current_token, -1); + find_recursively(store, &iter, result, tokens, depth+1); + } + } + + gtk_tree_model_iter_children(GTK_TREE_MODEL(store), &iter, root); + do { + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &str, -1); + if (g_strcmp0(current_token, str) == 0) { + find_recursively(store, &iter, result, tokens, depth+1); + g_free(str); + return; + } + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); + + g_free(str); + gtk_tree_store_append(store, &iter, root); + gtk_tree_store_set(store, &iter, 0, current_token, -1); + //*result = iter; + find_recursively(store, &iter, result, tokens, depth+1); +} + void fill_tree_store(GtkTreeStore *tree_store, struct uca_camera_t *cam) { GtkTreeIter iter, child; @@ -66,7 +136,6 @@ void fill_tree_store(GtkTreeStore *tree_store, struct uca_camera_t *cam) guint8 value_8; guint32 value_32; - gtk_tree_store_append(tree_store, &iter, NULL); for (int prop_id = 0; prop_id < UCA_PROP_LAST; prop_id++) { property = uca_get_full_property(prop_id); switch (property->type) { @@ -84,11 +153,22 @@ void fill_tree_store(GtkTreeStore *tree_store, struct uca_camera_t *cam) g_sprintf(value_string, "%d", value_32); break; } - gtk_tree_store_set(tree_store, &iter, - 0, property->name, + + /* Find first level root */ + gchar **tokens = g_strsplit(property->name, ".", 0); + get_first_level_root(tree_store, &iter, tokens[0]); + find_recursively(tree_store, &iter, &child, tokens, 1); + + int count = 0; + while (tokens[count++] != NULL); + + gtk_tree_store_set(tree_store, &child, + 0, tokens[count-2], 1, value_string, + 2, uca_unit_map[property->unit], -1); - gtk_tree_store_append(tree_store, &iter, NULL); + + g_strfreev(tokens); } g_free(value_string); diff --git a/test/control.glade b/test/control.glade index c56ddfe..dd9b829 100644 --- a/test/control.glade +++ b/test/control.glade @@ -8,10 +8,14 @@ <column type="gchararray"/> <!-- column-name PropertyValue --> <column type="gchararray"/> + <!-- column-name PropertyUnit --> + <column type="gchararray"/> </columns> </object> <object class="GtkWindow" id="window"> <property name="title" translatable="yes">Camera Control</property> + <property name="default_width">800</property> + <property name="default_height">600</property> <child> <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> @@ -171,6 +175,45 @@ <child> <object class="GtkToolbar" id="toolbar"> <property name="visible">True</property> + <child> + <object class="GtkToolButton" id="toolbutton_run"> + <property name="visible">True</property> + <property name="use_action_appearance">False</property> + <property name="label" translatable="yes">Run</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-media-play</property> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + <child> + <object class="GtkToolButton" id="toolbutton_record"> + <property name="visible">True</property> + <property name="use_action_appearance">False</property> + <property name="label" translatable="yes">Record</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-media-record</property> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + <child> + <object class="GtkToolButton" id="toolbutton_stop"> + <property name="visible">True</property> + <property name="use_action_appearance">False</property> + <property name="label" translatable="yes">Stop</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-media-stop</property> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> </object> <packing> <property name="expand">False</property> @@ -182,13 +225,27 @@ <property name="visible">True</property> <property name="can_focus">True</property> <child> - <object class="GtkImage" id="image"> + <object class="GtkScrolledWindow" id="scrolledwindow1"> <property name="visible">True</property> - <property name="stock">gtk-missing-image</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <child> + <object class="GtkViewport" id="viewport1"> + <property name="visible">True</property> + <property name="resize_mode">queue</property> + <child> + <object class="GtkImage" id="image"> + <property name="visible">True</property> + <property name="stock">gtk-missing-image</property> + </object> + </child> + </object> + </child> </object> <packing> - <property name="resize">False</property> - <property name="shrink">True</property> + <property name="resize">True</property> + <property name="shrink">False</property> </packing> </child> <child> @@ -218,9 +275,20 @@ </child> </object> </child> + <child> + <object class="GtkTreeViewColumn" id="unitcolumn"> + <property name="title" translatable="yes">Unit</property> + <child> + <object class="GtkCellRendererText" id="unitcell"/> + <attributes> + <attribute name="text">2</attribute> + </attributes> + </child> + </object> + </child> </object> <packing> - <property name="resize">True</property> + <property name="resize">False</property> <property name="shrink">True</property> </packing> </child> diff --git a/test/enum.c b/test/enum.c index 4c21f12..8803ec4 100644 --- a/test/enum.c +++ b/test/enum.c @@ -34,10 +34,6 @@ int main(int argc, char *argv[]) uint32_t uint32_value; uint8_t uint8_value; - const char *unit_map[] = { - "px", "bits", "ns", "µs", "ms", "s", "rows", "" - }; - while (cam != NULL) { for (int i = 0; i < UCA_PROP_LAST; i++) { struct uca_property_t *prop = uca_get_full_property(i); @@ -53,14 +49,14 @@ int main(int argc, char *argv[]) break; case uca_uint32t: if (cam->get_property(cam, i, &uint32_value) != UCA_ERR_PROP_INVALID) { - printf("%i %s", uint32_value, unit_map[prop->unit]); + printf("%i %s", uint32_value, uca_unit_map[prop->unit]); } else printf("n/a"); break; case uca_uint8t: if (cam->get_property(cam, i, &uint8_value) != UCA_ERR_PROP_INVALID) { - printf("%i %s", uint8_value, unit_map[prop->unit]); + printf("%i %s", uint8_value, uca_unit_map[prop->unit]); } else printf("n/a"); |