summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMatthias Vogelgesang <matthias.vogelgesang@gmail.com>2012-10-16 11:09:39 +0200
committerMatthias Vogelgesang <matthias.vogelgesang@gmail.com>2012-10-16 11:09:39 +0200
commite1ab5f557171c94c0b86203cd2ecb50bb9a52ab0 (patch)
tree7e8b6fbac7e5c6bbe6410f5e9c997075990f91b9 /tools
parent33a90d8dc20a513722f5fdf66a99cff91be422d5 (diff)
downloadlibuca-e1ab5f557171c94c0b86203cd2ecb50bb9a52ab0.tar.gz
libuca-e1ab5f557171c94c0b86203cd2ecb50bb9a52ab0.tar.bz2
libuca-e1ab5f557171c94c0b86203cd2ecb50bb9a52ab0.tar.xz
libuca-e1ab5f557171c94c0b86203cd2ecb50bb9a52ab0.zip
Add zoom functionality
Diffstat (limited to 'tools')
-rw-r--r--tools/gui/control.c103
-rw-r--r--tools/gui/control.glade90
2 files changed, 163 insertions, 30 deletions
diff --git a/tools/gui/control.c b/tools/gui/control.c
index f26cafc..c9fd2f6 100644
--- a/tools/gui/control.c
+++ b/tools/gui/control.c
@@ -41,6 +41,7 @@ typedef struct {
GtkWidget *start_button;
GtkWidget *stop_button;
GtkWidget *record_button;
+ GtkComboBox *zoom_box;
GtkWidget *histogram_view;
GtkToggleButton *histogram_button;
@@ -48,12 +49,13 @@ typedef struct {
RingBuffer *buffer;
guchar *pixels;
+ gint display_width, display_height;
+ gdouble zoom_factor;
State state;
- int timestamp;
- int width;
- int height;
- int pixel_size;
+ gint timestamp;
+ gint width, height;
+ gint pixel_size;
} ThreadData;
static UcaPluginManager *plugin_manager;
@@ -66,32 +68,42 @@ convert_grayscale_to_rgb (ThreadData *data, gpointer buffer)
gdouble max;
gdouble factor;
guint8 *output;
+ gint i = 0;
+ gint stride;
egg_histogram_get_visible_range (EGG_HISTOGRAM_VIEW (data->histogram_view), &min, &max);
factor = 255.0 / (max - min);
output = data->pixels;
+ stride = (gint) 1 / data->zoom_factor;
if (data->pixel_size == 1) {
guint8 *input = (guint8 *) buffer;
- for (int i = 0, j = 0; i < data->width * data->height; i++) {
- guchar val = (guchar) ((input[i] - min) * factor);
- output[j++] = val;
- output[j++] = val;
- output[j++] = val;
- /* if (i < 10) { */
- /* g_print ("%i->%i ", input[i], val); */
- /* } */
+ for (gint y = 0; y < data->display_height; y++) {
+ gint offset = y * stride * data->width;
+
+ for (gint x = 0; x < data->display_width; x++, offset += stride) {
+ guchar val = (guchar) ((input[offset] - min) * factor);
+
+ output[i++] = val;
+ output[i++] = val;
+ output[i++] = val;
+ }
}
}
else if (data->pixel_size == 2) {
guint16 *input = (guint16 *) buffer;
- for (int i = 0, j = 0; i < data->width * data->height; i++) {
- guchar val = (guint8) ((input[i] - min) * factor);
- output[j++] = val;
- output[j++] = val;
- output[j++] = val;
+ for (gint y = 0; y < data->display_height; y++) {
+ gint offset = y * stride * data->width;
+
+ for (gint x = 0; x < data->display_width; x++, offset += stride) {
+ guchar val = (guchar) ((input[offset] - min) * factor);
+
+ output[i++] = val;
+ output[i++] = val;
+ output[i++] = val;
+ }
}
}
}
@@ -100,14 +112,24 @@ static void
update_pixbuf (ThreadData *data)
{
gdk_flush ();
- gtk_image_clear (GTK_IMAGE (data->image));
gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf);
- gtk_widget_queue_draw_area (data->image, 0, 0, data->width, data->height);
+ gtk_widget_queue_draw_area (data->image, 0, 0, data->display_width, data->display_height);
if (gtk_toggle_button_get_active (data->histogram_button))
gtk_widget_queue_draw (data->histogram_view);
}
+static void
+update_pixbuf_dimensions (ThreadData *data)
+{
+ if (data->pixbuf != NULL)
+ g_object_unref (data->pixbuf);
+
+ data->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, data->display_width, data->display_height);
+ data->pixels = gdk_pixbuf_get_pixels (data->pixbuf);
+ gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf);
+}
+
static gpointer
preview_frames (void *args)
{
@@ -182,6 +204,8 @@ set_tool_button_state (ThreadData *data)
data->state == RUNNING || data->state == RECORDING);
gtk_widget_set_sensitive (data->record_button,
data->state == IDLE);
+ gtk_widget_set_sensitive (GTK_WIDGET (data->zoom_box),
+ data->state == IDLE);
}
static void
@@ -268,6 +292,28 @@ on_histogram_changed (EggHistogramView *view, ThreadData *data)
}
static void
+on_zoom_changed (GtkComboBox *widget, ThreadData *data)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gdouble factor;
+
+ enum {
+ DISPLAY_COLUMN,
+ FACTOR_COLUMN
+ };
+
+ model = gtk_combo_box_get_model (widget);
+ gtk_combo_box_get_active_iter (widget, &iter);
+ gtk_tree_model_get (model, &iter, FACTOR_COLUMN, &factor, -1);
+
+ data->display_width = (gint) data->width * factor;
+ data->display_height = (gint) data->height * factor;
+ data->zoom_factor = factor;
+ update_pixbuf_dimensions (data);
+}
+
+static void
create_main_window (GtkBuilder *builder, const gchar* camera_name)
{
static ThreadData td;
@@ -278,9 +324,9 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
GtkWidget *property_tree_view;
GdkPixbuf *pixbuf;
GtkBox *histogram_box;
- GtkContainer *property_window;
- GtkAdjustment *max_bin_adjustment;
- RingBuffer *ring_buffer;
+ GtkContainer *property_window;
+ GtkAdjustment *max_bin_adjustment;
+ RingBuffer *ring_buffer;
gsize image_size;
guint n_frames;
guint bits_per_sample;
@@ -309,6 +355,7 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
max_bin_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "max-bin-value-adjustment"));
+ td.zoom_box = GTK_COMBO_BOX (gtk_builder_get_object (builder, "zoom-box"));
td.start_button = GTK_WIDGET (gtk_builder_get_object (builder, "start-button"));
td.stop_button = GTK_WIDGET (gtk_builder_get_object (builder, "stop-button"));
td.record_button = GTK_WIDGET (gtk_builder_get_object (builder, "record-button"));
@@ -336,15 +383,18 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
td.pixel_size = pixel_size;
td.image = image;
- td.pixbuf = pixbuf;
+ td.pixbuf = NULL;
+ td.pixels = NULL;
td.buffer = ring_buffer;
- td.pixels = gdk_pixbuf_get_pixels (pixbuf);
td.state = IDLE;
td.camera = camera;
- td.width = width;
- td.height = height;
+ td.width = td.display_width = width;
+ td.height = td.display_height = height;
+ td.zoom_factor = 1.0;
td.histogram_view = histogram_view;
+ update_pixbuf_dimensions (&td);
+
/* Hook up signals */
g_object_bind_property (gtk_builder_get_object (builder, "min-bin-value-adjustment"), "value",
td.histogram_view, "minimum-bin-value",
@@ -358,6 +408,7 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
g_signal_connect (td.start_button, "clicked", G_CALLBACK (on_start_button_clicked), &td);
g_signal_connect (td.stop_button, "clicked", G_CALLBACK (on_stop_button_clicked), &td);
g_signal_connect (td.record_button, "clicked", G_CALLBACK (on_record_button_clicked), &td);
+ g_signal_connect (td.zoom_box, "changed", G_CALLBACK (on_zoom_changed), &td);
g_signal_connect (histogram_view, "changed", G_CALLBACK (on_histogram_changed), &td);
g_signal_connect (window, "destroy", G_CALLBACK (on_destroy), &td);
diff --git a/tools/gui/control.glade b/tools/gui/control.glade
index 90d9511..37f8150 100644
--- a/tools/gui/control.glade
+++ b/tools/gui/control.glade
@@ -200,6 +200,7 @@
<child>
<object class="GtkHBox" id="histogram-box">
<property name="visible">True</property>
+ <property name="border_width">10</property>
<child>
<placeholder/>
</child>
@@ -310,11 +311,70 @@
</packing>
</child>
<child>
- <object class="GtkHScale" id="hscale1">
+ <object class="GtkTable" id="table2">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="adjustment">frames-adjustment</property>
- <property name="digits">0</property>
+ <property name="border_width">10</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkHScale" id="hscale1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">frames-adjustment</property>
+ <property name="digits">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Frame:</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Zoom:</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="zoom-box">
+ <property name="visible">True</property>
+ <property name="model">zoom-values</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">1</property>
@@ -365,6 +425,28 @@
</object>
</child>
</object>
+ <object class="GtkListStore" id="zoom-values">
+ <columns>
+ <!-- column-name display -->
+ <column type="gchararray"/>
+ <!-- column-name factor -->
+ <column type="gdouble"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">100 %</col>
+ <col id="1">1</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">50 %</col>
+ <col id="1">0.5</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">25 %</col>
+ <col id="1">0.25</col>
+ </row>
+ </data>
+ </object>
<object class="GtkWindow" id="choice-window">
<property name="border_width">6</property>
<child>