/*! \brief Handles the press on a mouse button. * \par Function Description * It handles the user inputs. * * Three action are available: zoom in, pan and zoom out on preview display. * * \param [in] widget The preview widget. * \param [in] event The event structure. * \param [in] user_data Unused user data. * \returns FALSE to propagate the event further. */ static gboolean preview_callback_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { Preview *preview = PREVIEW (widget); GSCHEM_TOPLEVEL *preview_w_current = preview->preview_w_current; gint wx, wy; if (!preview->active) { return TRUE; } switch (event->button) { case 1: /* left mouse button: zoom in */ a_zoom (preview_w_current, ZOOM_IN, HOTKEY, A_PAN_DONT_REDRAW); o_invalidate_all (preview_w_current); break; case 2: /* middle mouse button: pan */ if (!x_event_get_pointer_position(preview_w_current, FALSE, &wx, &wy)) return FALSE; a_pan (preview_w_current, wx, wy); break; case 3: /* right mouse button: zoom out */ a_zoom (preview_w_current, ZOOM_OUT, HOTKEY, A_PAN_DONT_REDRAW); o_invalidate_all (preview_w_current); break; } return FALSE; }
/*! \brief Handles the press on a mouse button. * \par Function Description * It handles the user inputs. * * Three action are available: zoom in, pan and zoom out on preview display. * * \param [in] widget The preview widget. * \param [in] event The event structure. * \param [in] user_data Unused user data. * \returns FALSE to propagate the event further. */ static gboolean preview_callback_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { Preview *preview = PREVIEW (widget); GschemToplevel *preview_w_current = preview->preview_w_current; gint wx, wy; if (!preview->active) { return TRUE; } switch (event->button) { case 1: /* left mouse button: zoom in */ a_zoom (preview_w_current, GSCHEM_PAGE_VIEW (preview), ZOOM_IN, HOTKEY); gschem_page_view_invalidate_all (GSCHEM_PAGE_VIEW (widget)); break; case 2: /* middle mouse button: pan */ if (!x_event_get_pointer_position(preview_w_current, FALSE, &wx, &wy)) return FALSE; gschem_page_view_pan (GSCHEM_PAGE_VIEW (preview), wx, wy); break; case 3: /* right mouse button: zoom out */ a_zoom (preview_w_current, GSCHEM_PAGE_VIEW (preview), ZOOM_OUT, HOTKEY); gschem_page_view_invalidate_all (GSCHEM_PAGE_VIEW (widget)); break; } return FALSE; }
/* dir is either ZOOM_IN, ZOOM_OUT or ZOOM_FULL which are defined in globals.h */ void a_zoom(GschemToplevel *w_current, GschemPageView *page_view, int dir, int selected_from) { g_return_if_fail (page_view != NULL); GschemPageGeometry *geometry = gschem_page_view_get_page_geometry (page_view); g_return_if_fail (geometry != NULL); double world_pan_center_x,world_pan_center_y,relativ_zoom_factor = - 1; int start_x, start_y; double top, bottom, right, left; /* NB: w_current->zoom_gain is a percentage increase */ switch(dir) { case(ZOOM_IN): relativ_zoom_factor = (100.0 + w_current->zoom_gain) / 100.0; break; case(ZOOM_OUT): relativ_zoom_factor = 100.0 / (100.0 + w_current->zoom_gain); break; case(ZOOM_FULL): /* indicate the zoom full with a negative zoomfactor */ relativ_zoom_factor = -1; break; } /* calc center: either "mouse_to_world" or center=center or a virtual center if warp_cursor is disabled */ if (w_current->zoom_with_pan == TRUE && selected_from == HOTKEY) { if (!x_event_get_pointer_position(w_current, FALSE, &start_x, &start_y)) return; if ( w_current->warp_cursor ) { world_pan_center_x = start_x; world_pan_center_y = start_y; } else { left = ((geometry->viewport_left - start_x) * (1/relativ_zoom_factor) + start_x); right = ((geometry->viewport_right - start_x) * (1/relativ_zoom_factor) + start_x); top = ((geometry->viewport_top - start_y) * (1/relativ_zoom_factor) + start_y); bottom = ((geometry->viewport_bottom - start_y) * (1/relativ_zoom_factor) + start_y); world_pan_center_x = (right + left) / 2; world_pan_center_y = (top + bottom) / 2; } } else { world_pan_center_x = (double) (geometry->viewport_left + geometry->viewport_right) / 2; world_pan_center_y = (double) (geometry->viewport_top + geometry->viewport_bottom) / 2; } #if DEBUG printf("relative zoomfactor: %E\n", relativ_zoom_factor); printf("new center: x: %E, y: %E \n", world_pan_center_x, world_pan_center_y); #endif /* calculate new window and draw it */ gschem_page_view_pan_general (page_view, world_pan_center_x, world_pan_center_y, relativ_zoom_factor); /* Before warping the cursor, filter out any consecutive scroll events * from the event queue. If the program receives more than one scroll * event before it can process the first one, then the globals mouse_x * and mouse_y won't contain the proper mouse position, * because the handler for the mouse moved event needs to * run first to set these values. */ GdkEvent *topEvent = gdk_event_get(); while( topEvent != NULL ) { if( topEvent->type != GDK_SCROLL ) { gdk_event_put( topEvent ); gdk_event_free( topEvent ); break; } gdk_event_free( topEvent ); topEvent = gdk_event_get(); } /* warp the cursor to the right position */ if (w_current->warp_cursor) { gschem_page_view_WORLDtoSCREEN (page_view, world_pan_center_x, world_pan_center_y, &start_x, &start_y); x_basic_warp_cursor (GTK_WIDGET (page_view), start_x, start_y); } }