summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMariaMatveeva <matveeva.maria@gmail.com>2016-01-11 10:45:20 +0100
committerMariaMatveeva <matveeva.maria@gmail.com>2016-01-11 10:46:20 +0100
commit51e1019349db1b12efe840f84fee04b42ee27a13 (patch)
treea07a956340312e4407a4ad92ceb2e7ddd3d330c4
parenta32d701db454246162b2df5edf428bb0d16442fe (diff)
downloadlibuca-51e1019349db1b12efe840f84fee04b42ee27a13.tar.gz
libuca-51e1019349db1b12efe840f84fee04b42ee27a13.tar.bz2
libuca-51e1019349db1b12efe840f84fee04b42ee27a13.tar.xz
libuca-51e1019349db1b12efe840f84fee04b42ee27a13.zip
Fix GUI zoom problems
-rw-r--r--bin/gui/control.c369
1 files changed, 265 insertions, 104 deletions
diff --git a/bin/gui/control.c b/bin/gui/control.c
index 2532832..09b91ad 100644
--- a/bin/gui/control.c
+++ b/bin/gui/control.c
@@ -40,7 +40,6 @@ typedef struct {
UcaCamera *camera;
GtkWidget *main_window;
GdkPixbuf *pixbuf;
- GdkPixbuf *subpixbuf;
GtkWidget *image;
GtkWidget *start_button;
GtkWidget *stop_button;
@@ -52,6 +51,7 @@ typedef struct {
GtkWidget *rect_color_button;
GtkWidget *acquisition_expander;
GtkWidget *properties_expander;
+ GtkWidget *histogram_view;
GtkWidget *colormap_box;
GtkWidget *event_box;
GtkLabel *mean_label;
@@ -66,8 +66,6 @@ typedef struct {
GtkLabel *roiw_label;
GtkLabel *roih_label;
- GtkDialog *download_dialog;
- GtkProgressBar *download_progressbar;
GtkAdjustment *download_adjustment;
GtkAdjustment *count;
GtkAdjustment *hadjustment;
@@ -76,42 +74,51 @@ typedef struct {
GtkAdjustment *y_adjustment;
GtkAdjustment *width_adjustment;
GtkAdjustment *height_adjustment;
+ GtkAdjustment *frame_slider;
- GtkWidget *histogram_view;
+ GtkDialog *download_dialog;
+ GtkProgressBar *download_progressbar;
GtkToggleButton *histogram_button;
GtkToggleButton *log_button;
- GtkAdjustment *frame_slider;
+ UcaRingBuffer *buffer;
+ guchar *shadow;
+ guchar *pixels;
+ cairo_t *cr;
+ State state;
+ guint n_recorded;
+ gboolean data_in_camram;
+ gboolean stopped;
- UcaRingBuffer *buffer;
- guchar *shadow;
- guchar *pixels;
gint display_width, display_height;
- gint colormap;
- gdouble zoom_factor;
- gdouble zoom_before;
- State state;
- guint n_recorded;
- gboolean data_in_camram;
-
- gint timestamp;
+ gint pixbuf_width, pixbuf_height;
+ gint page_width, page_height;
+ gint adj_width, adj_height;
gint width, height;
- gint pixel_size;
- gint ev_x, ev_y;
gint display_x, display_y;
gint tmp_fromx, tmp_fromy;
+ gint rect_evx, rect_evy;
+ gint side_x, side_y;
+ gint rect_x, rect_y;
gint from_x, from_y;
gint to_x, to_y;
- gint adj_width, adj_height;
- gint rect_x, rect_y;
- gint rect_evx, rect_evy;
- cairo_t *cr;
+ gint ev_x, ev_y;
+ gint colormap;
+ gint timestamp;
+ gint pixel_size;
+ gint resize_counter;
+ gint mm_width, mm_height;
+
+ gdouble zoom_factor;
+ gdouble zoom_before;
gdouble red, green, blue;
+ gdouble percent_width, percent_height;
} ThreadData;
static UcaPluginManager *plugin_manager;
static gsize mem_size = 2048;
static void update_pixbuf (ThreadData *data, gpointer buffer);
+static void update_pixbuf_dimensions (ThreadData *data);
static void
up_and_down_scale (ThreadData *data, gpointer buffer)
@@ -126,62 +133,122 @@ up_and_down_scale (ThreadData *data, gpointer buffer)
gint zoom;
gint stride;
gint offset = 0;
- gint start_wval;
- gint start_hval;
+ gint min_x;
+ gint min_y;
+ gint max_x;
+ gint max_y;
+ gint current_width;
+ gint current_height;
+
+ current_width = gtk_adjustment_get_page_size (data->hadjustment);
+ current_height = gtk_adjustment_get_page_size (data->vadjustment);
+ if (((current_width > data->page_width || current_height > data->page_height)
+ && ((current_width - data->page_width) >= 15 || (current_height - data->page_height) >= 15))
+ || ((current_width < data->page_width || current_height < data->page_height)
+ && ((data->page_width - current_width) >= 15 || (data->page_height - current_height) >= 15))) {
+ data->resize_counter += 1;
+ if (data->resize_counter > 30) {
+ update_pixbuf_dimensions (data);
+ }
+ }
egg_histogram_get_range (EGG_HISTOGRAM_VIEW (data->histogram_view), &min, &max);
factor = 255.0 / (max - min);
output = data->pixels;
zoom = (gint) data->zoom_factor;
stride = (gint) 1 / data->zoom_factor;
- gint page_width = gtk_adjustment_get_page_size (GTK_ADJUSTMENT (data->hadjustment));
- gint page_height = gtk_adjustment_get_page_size (GTK_ADJUSTMENT (data->vadjustment));
do_log = gtk_toggle_button_get_active (data->log_button);
+ min_x = gtk_adjustment_get_value (data->hadjustment);
+ min_y = gtk_adjustment_get_value (data->vadjustment);
- if (data->state == RUNNING) {
- if ((data->adj_width > 0) && (data->adj_height > 0)) {
- start_wval = data->from_x;
- start_hval = data->from_y;
- page_width = data->to_x;
- page_height = data->to_y;
+ if (data->adj_width > 0 && data->adj_height > 0) {
+ min_x = data->from_x;
+ min_y = data->from_y;
+ max_x = data->pixbuf_width + min_x;
+ max_y = data->pixbuf_height + min_y;
+ }
+ else if (data->stopped == FALSE) {
+ if (data->display_width <= data->page_width || data->pixbuf_width == data->display_width)
+ max_x = data->display_width;
+ else
+ max_x = data->pixbuf_width + min_x;
+
+ if (data->display_height <= data->page_height || data->pixbuf_height == data->display_height)
+ max_y = data->display_height;
+ else
+ max_y = data->pixbuf_height + min_y;
+ }
+ else {
+ min_x = 0;
+ min_y = 0;
+ max_x = data->display_width;
+ max_y = data->display_height;
+ }
+
+ if (max_x > data->display_width) {
+ gint diff_x = max_x - data->display_width;
+ if ((min_x - diff_x) >= 0) {
+ min_x -= diff_x;
+ max_x -= diff_x;
}
else {
- start_wval = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->hadjustment));
- start_hval = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->vadjustment));
- page_width += start_wval;
- page_height += start_hval;
+ min_x = 0;
+ max_x = data->pixbuf_width;
}
}
- else {
- start_wval = 0;
- start_hval = 0;
- page_width = data->display_width;
- page_height = data->display_height;
+
+ if (max_y > data->display_height) {
+ gint diff_y = max_y - data->display_height;
+ if ((min_y - diff_y) >= 0) {
+ min_y -= diff_y;
+ max_y -= diff_y;
+ }
+ else {
+ min_y = 0;
+ max_y = data->pixbuf_height;
+ }
}
+ if ((data->display_width <= data->page_width) || (data->page_width == 1) ||
+ (data->adj_width > 0 && data->adj_height > 0 && data->adj_width <= data->page_width))
+ data->percent_width = 0.5;
+ else if ((min_x == 0 && data->display_width >= data->page_width) ||
+ (data->adj_width > 0 && data->adj_height > 0 && data->adj_width > data->page_width))
+ data->percent_width = 0.0;
+ else
+ data->percent_width = min_x / (gdouble) (data->display_width - data->page_width);
+
+ if ((data->display_height<= data->page_height) || (data->page_height == 1) ||
+ (data->adj_width > 0 && data->adj_height > 0 && data->adj_height <= data->page_height))
+ data->percent_height = 0.5;
+ else if ((min_y == 0 && data->display_height >= data->page_height) ||
+ (data->adj_width > 0 && data->adj_height > 0 && data->adj_height > data->page_height))
+ data->percent_height = 0.0;
+ else
+ data->percent_height = min_y / (gdouble) (data->display_height - data->page_height);
+
+ gtk_misc_set_alignment (GTK_MISC(data->image), data->percent_width, data->percent_height);
+
if (data->pixel_size == 1) {
guint8 *input = (guint8 *) buffer;
-
- for (gint y = 0; y < data->display_height; y++) {
- if (zoom <= 1) {
+ for (gint y = min_y; y < max_y; y++) {
+ if (zoom <= 1 && min_x == 0) {
offset = y * stride * data->width;
}
- for (gint x = 0; x < data->display_width; x++) {
- if (zoom <= 1)
+ for (gint x = min_x; x < max_x; x++) {
+ if (zoom <= 1 && min_x == 0)
offset += stride;
+ else if (zoom <= 1)
+ offset = (y * stride * data->width) + (x * stride);
else
offset = ((gint) (y / zoom) * data->width) + ((gint) (x / zoom));
- if (y >= start_hval && y < page_height) {
- if (x >= start_wval && x < page_width) {
+ if (do_log)
+ dval = log ((input[offset] - min) * factor);
+ else
+ dval = (input[offset] - min) * factor;
- if (do_log)
- dval = log ((input[offset] - min) * factor);
- else
- dval = (input[offset] - min) * factor;
- }
- }
guchar val = (guchar) CLAMP(dval, 0.0, 255.0);
if (data->colormap == 1) {
@@ -221,7 +288,6 @@ up_and_down_scale (ThreadData *data, gpointer buffer)
else {
red = 255 + 4 * (223.125 - val);
}
-
output[i++] = (guchar) red;
output[i++] = (guchar) green;
output[i++] = (guchar) blue;
@@ -232,26 +298,24 @@ up_and_down_scale (ThreadData *data, gpointer buffer)
else if (data->pixel_size == 2) {
guint16 *input = (guint16 *) buffer;
- for (gint y = 0; y < data->display_height; y++) {
- if (zoom <= 1) {
+ for (gint y = min_y; y < max_y; y++) {
+ if (zoom <= 1 && min_x == 0) {
offset = y * stride * data->width;
}
- for (gint x = 0; x < data->display_width; x++) {
- if (zoom <= 1)
+ for (gint x = min_x; x < max_x; x++) {
+ if (zoom <= 1 && min_x == 0)
offset += stride;
+ else if (zoom <= 1)
+ offset = (y * stride * data->width) + (x * stride);
else
offset = ((gint) (y / zoom) * data->width) + ((gint) (x / zoom));
- if (y >= start_hval && y < page_height) {
- if (x >= start_wval && x < page_width) {
+ if (do_log)
+ dval = log ((input[offset] - min) * factor);
+ else
+ dval = (input[offset] - min) * factor;
- if (do_log)
- dval = log ((input[offset] - min) * factor);
- else
- dval = (input[offset] - min) * factor;
- }
- }
guchar val = (guchar) CLAMP(dval, 0.0, 255.0);
if (data->colormap == 1) {
@@ -361,7 +425,21 @@ update_sidebar (ThreadData *data, gpointer buffer)
{
gchar string[32];
- gint i = (data->display_y / data->zoom_factor) * data->width + data->display_x / data->zoom_factor;
+ if (data->display_x < 0)
+ data->side_x = 0;
+ else if (data->display_x > data->display_width)
+ data->side_x = data->display_width;
+ else
+ data->side_x = data->display_x;
+
+ if (data->display_y < 0)
+ data->side_y = 0;
+ else if (data->display_y > data->display_height)
+ data->side_y = data->display_height;
+ else
+ data->side_y = data->display_y;
+
+ gint i = (data->side_y / data->zoom_factor) * data->width + (data->side_x / data->zoom_factor);
if (data->pixel_size == 1) {
guint8 *input = (guint8 *) buffer;
@@ -376,20 +454,21 @@ update_sidebar (ThreadData *data, gpointer buffer)
gtk_label_set_text (data->val_label, string);
}
- g_snprintf (string, 32, "x = %i", data->display_x);
+ g_snprintf (string, 32, "x = %i", data->side_x);
gtk_label_set_text (data->x_label, string);
- g_snprintf (string, 32, "y = %i", data->display_y);
+ g_snprintf (string, 32, "y = %i", data->side_y);
gtk_label_set_text (data->y_label, string);
}
static void
on_motion_notify (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data)
{
- gint page_width = gtk_adjustment_get_page_size(GTK_ADJUSTMENT(data->hadjustment));
- gint page_height = gtk_adjustment_get_page_size(GTK_ADJUSTMENT(data->vadjustment));
- gint start_wval = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->hadjustment));
- gint start_hval = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->vadjustment));
+ gint page_width = gtk_adjustment_get_page_size (data->hadjustment);
+ gint page_height = gtk_adjustment_get_page_size (data->vadjustment);
+ gint start_wval = gtk_adjustment_get_value (data->hadjustment);
+ gint start_hval = gtk_adjustment_get_value (data->vadjustment);
+
page_width += start_wval;
page_height += start_hval;
data->rect_evx = event->x;
@@ -473,10 +552,16 @@ on_button_press (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data)
normalize_event_coords (data);
- gtk_adjustment_set_upper (GTK_ADJUSTMENT (data->x_adjustment), data->display_width);
- gtk_adjustment_set_upper (GTK_ADJUSTMENT (data->y_adjustment), data->display_height);
- gtk_adjustment_set_value (GTK_ADJUSTMENT (data->x_adjustment), data->ev_x);
- gtk_adjustment_set_value (GTK_ADJUSTMENT (data->y_adjustment), data->ev_y);
+ gtk_adjustment_set_upper (data->x_adjustment, data->display_width);
+ gtk_adjustment_set_upper (data->y_adjustment, data->display_height);
+ if (data->adj_width > 0 && data->adj_height > 0) {
+ gtk_adjustment_set_value (data->x_adjustment, data->side_x);
+ gtk_adjustment_set_value (data->y_adjustment, data->side_y);
+ }
+ else {
+ gtk_adjustment_set_value (data->x_adjustment, data->ev_x);
+ gtk_adjustment_set_value (data->y_adjustment, data->ev_y);
+ }
data->tmp_fromx = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->x_adjustment));
data->tmp_fromy = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->y_adjustment));
@@ -492,13 +577,19 @@ on_button_release (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data
normalize_event_coords (data);
- gtk_adjustment_set_upper (GTK_ADJUSTMENT (data->width_adjustment), data->display_width);
- gtk_adjustment_set_upper (GTK_ADJUSTMENT (data->height_adjustment), data->display_height);
- gtk_adjustment_set_value (GTK_ADJUSTMENT (data->width_adjustment), data->ev_x);
- gtk_adjustment_set_value (GTK_ADJUSTMENT (data->height_adjustment), data->ev_y);
+ gtk_adjustment_set_upper (data->width_adjustment, data->display_width);
+ gtk_adjustment_set_upper (data->height_adjustment, data->display_height);
+ if (data->adj_width > 0 && data->adj_height > 0) {
+ gtk_adjustment_set_value (data->width_adjustment, data->side_x);
+ gtk_adjustment_set_value (data->height_adjustment, data->side_y);
+ }
+ else {
+ gtk_adjustment_set_value (data->width_adjustment, data->ev_x);
+ gtk_adjustment_set_value (data->height_adjustment, data->ev_y);
+ }
- gint tmp_tox = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->width_adjustment));
- gint tmp_toy = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->height_adjustment));
+ gint tmp_tox = gtk_adjustment_get_value (data->width_adjustment);
+ gint tmp_toy = gtk_adjustment_get_value (data->height_adjustment);
if (data->tmp_fromx > tmp_tox) {
data->from_x = tmp_tox;
@@ -520,9 +611,17 @@ on_button_release (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data
data->adj_width = data->to_x - data->from_x;
data->adj_height = data->to_y - data->from_y;
+ if (data->adj_width < 40 && data->adj_height < 40) {
+ data->adj_width = 0;
+ data->adj_height = 0;
+ }
+
+ update_pixbuf_dimensions (data);
+ up_and_down_scale (data, uca_ring_buffer_peek_pointer (data->buffer));
update_pixbuf (data, uca_ring_buffer_peek_pointer (data->buffer));
}
+
static gboolean
on_expose (GtkWidget *event_box, GdkEventExpose *event, ThreadData *data)
{
@@ -554,21 +653,14 @@ update_pixbuf (ThreadData *data, gpointer buffer)
gdk_flush ();
- if (data->adj_width > 0 && data->adj_height > 0) {
- data->subpixbuf = gdk_pixbuf_new_subpixbuf (data->pixbuf, data->from_x, data->from_y, data->adj_width, data->adj_height);
- gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->subpixbuf);
- }
- else {
- gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf);
- }
-
- gtk_widget_queue_draw_area (data->image, 0, 0, data->display_width, data->display_height);
+ gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf);
+ gtk_widget_queue_draw (data->image);
- if ((data->adj_width > 0) && (data->adj_height > 0)) {
+ if (data->adj_width > 0 && data->adj_height > 0) {
x = data->from_x;
y = data->from_y;
- width = data->adj_width;
- height = data->adj_height;
+ width = data->pixbuf_width;
+ height = data->pixbuf_height;
}
else {
width = data->display_width;
@@ -611,13 +703,28 @@ update_pixbuf_dimensions (ThreadData *data)
if (data->pixbuf != NULL)
g_object_unref (data->pixbuf);
+ gint filling_up;
+ gint width_remainder;
+ gint height_remainder;
+ gint event_width;
+ gint event_height;
+
+ data->display_width = (gint) data->width * data->zoom_factor;
+ data->display_height = (gint) data->height * data->zoom_factor;
+ filling_up = data->pixel_size * 4;
+ data->resize_counter = 0;
+
+ if ((gint) data->zoom_factor == 32)
+ gtk_widget_set_sensitive (data->zoom_in_button, FALSE);
+ else
+ gtk_widget_set_sensitive (data->zoom_in_button, TRUE);
+
if (data->adj_width > 0 && data->adj_height > 0) {
gdouble zoom = data->zoom_factor / data->zoom_before;
-
- data->from_x = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->x_adjustment)) * zoom;
- data->from_y = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->y_adjustment)) * zoom;
- data->to_x = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->width_adjustment)) * zoom;
- data->to_y = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->height_adjustment)) * zoom;
+ data->from_x = gtk_adjustment_get_value (data->x_adjustment) * zoom;
+ data->from_y = gtk_adjustment_get_value (data->y_adjustment) * zoom;
+ data->to_x = gtk_adjustment_get_value (data->width_adjustment) * zoom;
+ data->to_y = gtk_adjustment_get_value (data->height_adjustment) * zoom;
gint adj_x = data->from_x;
gint adj_y = data->from_y;
@@ -632,12 +739,42 @@ update_pixbuf_dimensions (ThreadData *data)
}
data->adj_width = data->to_x - data->from_x;
data->adj_height = data->to_y - data->from_y;
+
+ data->pixbuf_width = data->adj_width;
+ data->pixbuf_height = data->adj_height;
}
+ else {
+ data->page_width = gtk_adjustment_get_page_size (data->hadjustment);
+ data->page_height = gtk_adjustment_get_page_size (data->vadjustment);
- data->display_width = (gint) data->width * data->zoom_factor;
- data->display_height = (gint) data->height * data->zoom_factor;
+ if (data->display_width <= data->page_width || data->stopped == TRUE || data->page_width == 1)
+ data->pixbuf_width = data->display_width;
+ else
+ data->pixbuf_width = data->page_width;
+
+ if (data->display_height <= data->page_height || data->stopped == TRUE || data->page_height == 1)
+ data->pixbuf_height = data->display_height;
+ else
+ data->pixbuf_height = data->page_height;
+ }
+
+ width_remainder = data->pixbuf_width % filling_up;
+ height_remainder = data->pixbuf_height % filling_up;
+ if (width_remainder != 0)
+ data->pixbuf_width += (filling_up - width_remainder);
+ if (height_remainder != 0)
+ data->pixbuf_height += (filling_up - height_remainder);
+
+ event_width = data->pixbuf_width;
+ event_height = data->pixbuf_height;
+ if ((data->display_width > event_width) && (data->adj_width <= 0 || data->adj_height <= 0))
+ event_width = data->display_width;
- data->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, data->display_width, data->display_height);
+ if ((data->display_height > event_height) && (data->adj_width <= 0 || data->adj_height <=0))
+ event_height = data->display_height;
+
+ gtk_widget_set_size_request (data->event_box, event_width, event_height);
+ data->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, data->pixbuf_width, data->pixbuf_height);
data->pixels = gdk_pixbuf_get_pixels (data->pixbuf);
gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf);
}
@@ -878,6 +1015,8 @@ static void
on_start_button_clicked (GtkWidget *widget, ThreadData *data)
{
GError *error = NULL;
+ data->stopped = FALSE;
+ update_pixbuf_dimensions (data);
uca_camera_start_recording (data->camera, &error);
@@ -905,6 +1044,8 @@ on_stop_button_clicked (GtkWidget *widget, ThreadData *data, GtkAdjustment *adju
data->state = IDLE;
set_tool_button_state (data);
uca_camera_stop_recording (data->camera, &error);
+ data->stopped = TRUE;
+ update_pixbuf_dimensions (data);
on_frame_slider_changed (adjustment, data);
@@ -1022,6 +1163,25 @@ update_zoomed_pixbuf (ThreadData *data)
up_and_down_scale (data, uca_ring_buffer_peek_pointer (data->buffer));
update_pixbuf (data, uca_ring_buffer_peek_pointer (data->buffer));
}
+
+ gint min_x;
+ gint min_y;
+ gint zoomed_min_x;
+ gint zoomed_min_y;
+
+ min_x = gtk_adjustment_get_value(data->hadjustment);
+ min_y = gtk_adjustment_get_value(data->vadjustment);
+
+ if ((data->percent_width != 0.0) || (data->percent_height != 0.0)) {
+ if (min_x != 0) {
+ zoomed_min_x = data->percent_width * (data->width * data->zoom_factor - data->page_width);
+ gtk_adjustment_set_value (data->hadjustment, zoomed_min_x);
+ }
+ if (min_y != 0) {
+ zoomed_min_y = data->percent_height * (data->height * data->zoom_factor - data->page_height);
+ gtk_adjustment_set_value (data->vadjustment, zoomed_min_y);
+ }
+ }
}
static void
@@ -1225,6 +1385,7 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
td.colormap = 1;
td.histogram_view = histogram_view;
td.data_in_camram = FALSE;
+ td.stopped = TRUE;
td.main_window = window;
update_pixbuf_dimensions (&td);