OpenFPGA/libs/EXTERNAL/libezgl/src/callback.cpp

253 lines
7.3 KiB
C++
Raw Normal View History

/*
* Copyright 2019 University of Toronto
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Authors: Mario Badr, Sameh Attia and Tanner Young-Schultz
*/
#include "ezgl/callback.hpp"
namespace ezgl {
// File wide static variables to track whether the middle mouse
// button is currently pressed AND the old x and y positions of the mouse pointer
bool middle_mouse_button_pressed = false;
int last_panning_event_time = 0;
double prev_x = 0, prev_y = 0;
gboolean press_key(GtkWidget *, GdkEventKey *event, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
// Call the user-defined key press callback if defined
if(application->key_press_callback != nullptr) {
// see: https://developer.gnome.org/gdk3/stable/gdk3-Keyboard-Handling.html
application->key_press_callback(application, event, gdk_keyval_name(event->keyval));
}
return FALSE; // propagate the event
}
gboolean press_mouse(GtkWidget *, GdkEventButton *event, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
if(event->type == GDK_BUTTON_PRESS) {
// Check for Middle mouse press to support dragging
if(event->button == 2) {
middle_mouse_button_pressed = true;
prev_x = event->x;
prev_y = event->y;
}
// Call the user-defined mouse press callback if defined
if(application->mouse_press_callback != nullptr) {
ezgl::point2d const widget_coordinates(event->x, event->y);
std::string main_canvas_id = application->get_main_canvas_id();
ezgl::canvas *canvas = application->get_canvas(main_canvas_id);
ezgl::point2d const world = canvas->get_camera().widget_to_world(widget_coordinates);
application->mouse_press_callback(application, event, world.x, world.y);
}
}
return TRUE; // consume the event
}
gboolean release_mouse(GtkWidget *, GdkEventButton *event, gpointer )
{
if(event->type == GDK_BUTTON_RELEASE) {
// Check for Middle mouse release to support dragging
if(event->button == 2) {
middle_mouse_button_pressed = false;
}
}
return TRUE; // consume the event
}
gboolean move_mouse(GtkWidget *, GdkEventButton *event, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
if(event->type == GDK_MOTION_NOTIFY) {
// Check if the middle mouse is pressed to support dragging
if(middle_mouse_button_pressed) {
// drop this panning event if we have just served another one
if(gtk_get_current_event_time() - last_panning_event_time < 100)
return true;
last_panning_event_time = gtk_get_current_event_time();
GdkEventMotion *motion_event = (GdkEventMotion *)event;
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
point2d curr_trans = canvas->get_camera().widget_to_world({motion_event->x, motion_event->y});
point2d prev_trans = canvas->get_camera().widget_to_world({prev_x, prev_y});
double dx = curr_trans.x - prev_trans.x;
double dy = curr_trans.y - prev_trans.y;
prev_x = motion_event->x;
prev_y = motion_event->y;
// Flip the delta x to avoid inverted dragging
translate(canvas, -dx, -dy);
}
// Else call the user-defined mouse move callback if defined
else if(application->mouse_move_callback != nullptr) {
ezgl::point2d const widget_coordinates(event->x, event->y);
std::string main_canvas_id = application->get_main_canvas_id();
ezgl::canvas *canvas = application->get_canvas(main_canvas_id);
ezgl::point2d const world = canvas->get_camera().widget_to_world(widget_coordinates);
application->mouse_move_callback(application, event, world.x, world.y);
}
}
return TRUE; // consume the event
}
gboolean scroll_mouse(GtkWidget *, GdkEvent *event, gpointer data)
{
if(event->type == GDK_SCROLL) {
auto application = static_cast<ezgl::application *>(data);
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
GdkEventScroll *scroll_event = (GdkEventScroll *)event;
ezgl::point2d scroll_point(scroll_event->x, scroll_event->y);
if(scroll_event->direction == GDK_SCROLL_UP) {
// Zoom in at the scroll point
ezgl::zoom_in(canvas, scroll_point, 5.0 / 3.0);
} else if(scroll_event->direction == GDK_SCROLL_DOWN) {
// Zoom out at the scroll point
ezgl::zoom_out(canvas, scroll_point, 5.0 / 3.0);
} else if(scroll_event->direction == GDK_SCROLL_SMOOTH) {
// Doesn't seem to be happening
} // NOTE: We ignore scroll GDK_SCROLL_LEFT and GDK_SCROLL_RIGHT
}
return TRUE;
}
gboolean press_zoom_fit(GtkWidget *, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
ezgl::zoom_fit(canvas, canvas->get_camera().get_initial_world());
return TRUE;
}
gboolean press_zoom_in(GtkWidget *, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
ezgl::zoom_in(canvas, 5.0 / 3.0);
return TRUE;
}
gboolean press_zoom_out(GtkWidget *, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
ezgl::zoom_out(canvas, 5.0 / 3.0);
return TRUE;
}
gboolean press_up(GtkWidget *, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
ezgl::translate_up(canvas, 5.0);
return TRUE;
}
gboolean press_down(GtkWidget *, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
ezgl::translate_down(canvas, 5.0);
return TRUE;
}
gboolean press_left(GtkWidget *, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
ezgl::translate_left(canvas, 5.0);
return TRUE;
}
gboolean press_right(GtkWidget *, gpointer data)
{
auto application = static_cast<ezgl::application *>(data);
std::string main_canvas_id = application->get_main_canvas_id();
auto canvas = application->get_canvas(main_canvas_id);
ezgl::translate_right(canvas, 5.0);
return TRUE;
}
gboolean press_proceed(GtkWidget *, gpointer data)
{
auto ezgl_app = static_cast<ezgl::application *>(data);
ezgl_app->quit();
return TRUE;
}
}