From 90e1289637453e58c6a5496a34c3233f871eedda Mon Sep 17 00:00:00 2001 From: MariaMatveeva Date: Fri, 29 Jan 2016 14:31:00 +0100 Subject: Faster zoom out, fix coordinates --- bin/gui/control.c | 183 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 104 insertions(+), 79 deletions(-) diff --git a/bin/gui/control.c b/bin/gui/control.c index 2e0c471..f59460d 100644 --- a/bin/gui/control.c +++ b/bin/gui/control.c @@ -93,6 +93,7 @@ typedef struct { gint pixbuf_width, pixbuf_height; gint page_width, page_height; gint adj_width, adj_height; + gint sub_width, sub_height; gint width, height; gint display_x, display_y; gint tmp_fromx, tmp_fromy; @@ -137,6 +138,8 @@ up_and_down_scale (ThreadData *data, gpointer buffer) gint min_y; gint max_x; gint max_y; + gint current_x; + gint current_y; gint current_width; gint current_height; @@ -160,10 +163,18 @@ up_and_down_scale (ThreadData *data, gpointer buffer) 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); + current_x = min_x; + current_y = min_y; if (data->adj_width > 0 && data->adj_height > 0) { - min_x = data->from_x; - min_y = data->from_y; + if (data->stopped == TRUE) { + min_x = data->from_x; + min_y = data->from_y; + } + else { + min_x = data->from_x + current_x; + min_y = data->from_y + current_y; + } max_x = data->pixbuf_width + min_x; max_y = data->pixbuf_height + min_y; } @@ -212,18 +223,20 @@ up_and_down_scale (ThreadData *data, gpointer buffer) 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)) + 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->stopped == TRUE)) data->percent_width = 0.0; + else if (data->adj_width > 0 && data->adj_height > 0 && data->adj_width > data->page_width) + data->percent_width = current_x / (gdouble) (data->adj_width - data->page_width); 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)) + else if ((min_y == 0 && data->display_height >= data->page_height) || (data->adj_width > 0 && data->adj_height > 0 && data->adj_width > data->page_width && data->stopped == TRUE)) data->percent_height = 0.0; + else if (data->adj_width > 0 && data->adj_height > 0 && data->adj_height > data->page_height) + data->percent_height = current_y / (gdouble) (data->adj_height - data->page_height); else data->percent_height = min_y / (gdouble) (data->display_height - data->page_height); @@ -232,14 +245,8 @@ up_and_down_scale (ThreadData *data, gpointer buffer) if (data->pixel_size == 1) { guint8 *input = (guint8 *) buffer; for (gint y = min_y; y < max_y; y++) { - if (zoom <= 1 && min_x == 0) { - offset = y * stride * data->width; - } - for (gint x = min_x; x < max_x; x++) { - if (zoom <= 1 && min_x == 0) - offset += stride; - else if (zoom <= 1) + if (zoom <= 1) offset = (y * stride * data->width) + (x * stride); else offset = ((gint) (y / zoom) * data->width) + ((gint) (x / zoom)); @@ -299,14 +306,8 @@ up_and_down_scale (ThreadData *data, gpointer buffer) guint16 *input = (guint16 *) buffer; for (gint y = min_y; y < max_y; y++) { - if (zoom <= 1 && min_x == 0) { - offset = y * stride * data->width; - } - for (gint x = min_x; x < max_x; x++) { - if (zoom <= 1 && min_x == 0) - offset += stride; - else if (zoom <= 1) + if (zoom <= 1) offset = (y * stride * data->width) + (x * stride); else offset = ((gint) (y / zoom) * data->width) + ((gint) (x / zoom)); @@ -427,19 +428,19 @@ update_sidebar (ThreadData *data, gpointer buffer) if (data->display_x < 0) data->side_x = 0; - else if (data->display_x > data->display_width) - data->side_x = data->display_width; + else if (data->display_x > data->display_width - 1) + data->side_x = data->width - 1; else - data->side_x = data->display_x; + data->side_x = data->display_x / data->zoom_factor; if (data->display_y < 0) data->side_y = 0; - else if (data->display_y > data->display_height) - data->side_y = data->display_height; + else if (data->display_y > data->display_height - 1) + data->side_y = data->height - 1; else - data->side_y = data->display_y; + data->side_y = data->display_y / data->zoom_factor; - gint i = (data->side_y / data->zoom_factor) * data->width + (data->side_x / data->zoom_factor); + gint i = data->side_y * data->width + data->side_x; if (data->pixel_size == 1) { guint8 *input = (guint8 *) buffer; @@ -474,39 +475,44 @@ on_motion_notify (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data) data->rect_evx = event->x; data->rect_evy = event->y; - if ((data->display_width < page_width) && (data->display_height < page_height)) { + if (data->display_width < page_width) { gint startx = (page_width - data->display_width) / 2; - gint starty = (page_height - data->display_height) / 2; - data->ev_x = event->x - startx; - data->ev_y = event->y - starty; - - if ((data->adj_width > 0) && (data->adj_height > 0)) { + if ((data->adj_width > 0) && (data->adj_height > 0)) data->display_x = event->x - ((page_width - data->adj_width) / 2) + data->from_x; - data->display_y = event->y - ((page_height - data->adj_height) / 2) + data->from_y; - } - else { + else data->display_x = data->ev_x; - data->display_y = data->ev_y; - } } else { data->ev_x = event->x; - data->ev_y = event->y; - if ((data->adj_width > 0) && (data->adj_height > 0)) { if (data->adj_width >= page_width) data->display_x = event->x + data->from_x; else data->display_x = event->x - ((page_width - data->adj_width) / 2) + data->from_x; + } + else { + data->display_x = data->ev_x; + } + } + if (data->display_height < page_height) { + gint starty = (page_height - data->display_height) / 2; + data->ev_y = event->y - starty; + if ((data->adj_width > 0) && (data->adj_height > 0)) + data->display_y = event->y - ((page_height - data->adj_height) / 2) + data->from_y; + else + data->display_y = data->ev_y; + } + else { + data->ev_y = event->y; + if ((data->adj_width > 0) && (data->adj_height > 0)) { if (data->adj_height >= page_height) data->display_y = event->y + data->from_y; else data->display_y = event->y - ((page_height - data->adj_height) / 2) + data->from_y; } else { - data->display_x = data->ev_x; data->display_y = data->ev_y; } } @@ -555,8 +561,8 @@ on_button_press (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data) 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); + gtk_adjustment_set_value (data->x_adjustment, data->display_x); + gtk_adjustment_set_value (data->y_adjustment, data->display_y); } else { gtk_adjustment_set_value (data->x_adjustment, data->ev_x); @@ -580,8 +586,8 @@ on_button_release (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data 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); + gtk_adjustment_set_value (data->width_adjustment, data->display_x); + gtk_adjustment_set_value (data->height_adjustment, data->display_y); } else { gtk_adjustment_set_value (data->width_adjustment, data->ev_x); @@ -611,11 +617,6 @@ 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)); @@ -650,10 +651,37 @@ update_pixbuf (ThreadData *data, gpointer buffer) guint height; guint x = 0; guint y = 0; + gint sub_x = 0; + gint sub_y = 0; + gint sub_width = 0; + gint sub_height = 0; gdk_flush (); - gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf); + if (data->sub_width != 0 || data->sub_height != 0) { + sub_width = data->sub_width; + sub_height = data->sub_height; + } + else { + sub_x = gtk_adjustment_get_value (data->hadjustment); + sub_y = gtk_adjustment_get_value (data->vadjustment); + if (sub_x == 0 && data->pixbuf_width == data->display_width) + sub_width = data->pixbuf_width - 1; + if (sub_y == 0 && data->pixbuf_height == data->display_height) + sub_height = data->pixbuf_height - 1; + if (sub_width != 0 && sub_height == 0) + sub_height = data->pixbuf_height; + if (sub_width == 0 && sub_height != 0) + sub_width = data->pixbuf_width; + } + + if ((sub_width > 0 && sub_height > 0) && (data->pixbuf_width < data->page_width || data->pixbuf_height < data->page_height)) { + GdkPixbuf *subpixbuf = gdk_pixbuf_new_subpixbuf (data->pixbuf, sub_x, sub_y, sub_width, sub_height); + gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), subpixbuf); + } + else { + 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) { @@ -713,6 +741,8 @@ update_pixbuf_dimensions (ThreadData *data) data->display_height = (gint) data->height * data->zoom_factor; filling_up = data->pixel_size * 4; data->resize_counter = 0; + data->sub_width = 0; + data->sub_height = 0; if ((gint) data->zoom_factor == 32) gtk_widget_set_sensitive (data->zoom_in_button, FALSE); @@ -740,26 +770,39 @@ 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; + if ((data->adj_width > data->page_width) && (data->stopped == FALSE)) + data->pixbuf_width = data->page_width; + else + data->pixbuf_width = data->adj_width; + + if ((data->adj_height > data->page_height) && (data->stopped == FALSE)) + data->pixbuf_height = data->page_height; + else + 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); if (data->display_width <= data->page_width || data->stopped == TRUE || data->page_width == 1) - data->pixbuf_width = data->display_width; + data->pixbuf_width = data->display_width - 1; 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; + data->pixbuf_height = data->display_height - 1; 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 || height_remainder != 0) { + data->sub_width = data->pixbuf_width; + data->sub_height = data->pixbuf_height; + } + if (width_remainder != 0) data->pixbuf_width += (filling_up - width_remainder); if (height_remainder != 0) @@ -769,9 +812,13 @@ update_pixbuf_dimensions (ThreadData *data) event_height = data->pixbuf_height; if ((data->display_width > event_width) && (data->adj_width <= 0 || data->adj_height <= 0)) event_width = data->display_width; + else if ((data->adj_width > event_width) && (data->adj_width > 0 && data->adj_height > 0 && data->stopped == FALSE)) + event_width = data->adj_width; - if ((data->display_height > event_height) && (data->adj_width <= 0 || data->adj_height <=0)) + if ((data->display_height > event_height) && (data->adj_width <= 0 || data->adj_height <= 0)) event_height = data->display_height; + else if ((data->adj_height > event_height) && (data->adj_width > 0 && data->adj_height > 0 && data->stopped == FALSE)) + event_height = data->adj_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); @@ -806,22 +853,6 @@ set_tool_button_state (ThreadData *data) data->state == IDLE); } -static gpointer -grab_async (void *args) -{ - ThreadData *data = (ThreadData *) args; - GError *error = NULL; - - while (data->state == RUNNING) { - uca_camera_grab (data->camera, data->shadow, &error); - - if (error != NULL) - print_and_free_error (&error); - } - - return NULL; -} - static gpointer preview_frames (void *args) { @@ -834,15 +865,9 @@ preview_frames (void *args) uca_camera_grab (data->camera, data->shadow, &error); - if (!g_thread_create (grab_async, data, FALSE, &error)) { - g_printerr ("Failed to create thread: %s\n", error->message); - data->state = IDLE; - set_tool_button_state (data); - return NULL; - } - while (data->state == RUNNING) { up_and_down_scale (data, data->shadow); + uca_camera_grab (data->camera, data->shadow, &error); gdk_threads_enter (); -- cgit v1.2.3