zoompan.cxx
Go to the documentation of this file.
1 #include <gtk/gtk.h>
2 #include <stdint.h>
3 #include <vector>
4 #include "event.h"
5 #include "geo.h"
6 #include "drawing.h"
7 #include "zoompan.h"
8 
9 extern int pixx, pixy;
10 extern int FDpixy, FDpixx;
11 extern int NDpixy, NDpixx;
12 extern bool isfd;
13 
14 extern std::vector<noeevent> theevents;
15 extern int gevi;
16 
18 
19 static int xonbutton1 = 0, yonbutton1 = 0;
20 static int newbuttonpush = false;
21 gboolean mousebuttonpress(__attribute__((unused)) GtkWidget * widg,
22  GdkEventMotion * gevent,
23  __attribute__((unused)) gpointer data)
24 {
25  xonbutton1 = gevent->x;
26  yonbutton1 = gevent->y;
27  newbuttonpush = true;
28  return TRUE;
29 }
30 
31 void dopanning(const noe_view_t V, GdkEventMotion * gevent)
32 {
33  int * yoffset = V == kX?&screenyoffset_xview:&screenyoffset_yview;
34 
35  static int oldx = xonbutton1, oldy = yonbutton1;
36  if(newbuttonpush){
37  oldx = xonbutton1, oldy = yonbutton1;
38  newbuttonpush = false;
39  }
40 
41  screenxoffset += oldx - gevent->x;
42  *yoffset += oldy - gevent->y;
43 
44  oldx = gevent->x, oldy = gevent->y;
45 
46  redraw_event(NULL, NULL, NULL);
47 }
48 
49 // True if we are zoomed, i.e. not at the full detector view.
50 static bool zoomed()
51 {
52  return (isfd && pixx != FDpixx) || (!isfd && pixx != NDpixx);
53 }
54 
55 gboolean dozooming(GtkWidget * widg, GdkEventScroll * gevent, gpointer data)
56 {
57  const bool up = gevent->direction == GDK_SCROLL_UP;
58 
59  const noe_view_t V = (*(bool *)data)?kY:kX;
60  int * yoffset = V == kX?&screenyoffset_xview:&screenyoffset_yview;
61  int * other_yoffset = V == kY?&screenyoffset_xview:&screenyoffset_yview;
62 
63  const int plane = screen_to_plane_unbounded(V, (int)gevent->x);
64  const int cell = screen_to_cell_unbounded (V, (int)gevent->x, (int)gevent->y);
65 
66  // Pixels away from the plane left edge and cell top edge
67  const int planepix = (int)gevent->x - det_to_screen_x(plane);
68  const int cellpix = (int)gevent->y - det_to_screen_y(plane, cell);
69 
70  // In the view *not* being moused-over, zoom in y around the center of the
71  // view. This assumes the two views have the same size on the screen.
72  const int other_cell = screen_to_cell_unbounded(V==kX?kY:kX,
73  (int)gevent->x, widg->allocation.height/2);
74 
75  const int old_pixy = pixy, old_pixx = pixx;
76 
77  if(up){
78  if(pixy > 10) pixy *= 1.1;
79  else pixy++;
80  }
81  else{
82  if(pixy > 10) pixy = std::max(isfd?FDpixy:NDpixy, int(pixy*0.9));
83  else pixy = std::max(isfd?FDpixy:NDpixy, pixy-1);
84  }
85 
86  if(old_pixy == pixy) return TRUE;
87 
89 
90  // Pick offsets that keep the center of the cell the pointer is over
91  // under the pointer. Try to keep the same part of the cell under
92  // the mouse so that zooming is roughly reversable.
93  const int newtoleft = det_to_screen_x(plane)
94  + pixx*(float(planepix)/old_pixx);
95  screenxoffset += newtoleft - (int)gevent->x;
96 
97  const int newtotop = det_to_screen_y(plane, cell)
98  + pixy*(float(cellpix)/old_pixy);
99  *yoffset += newtotop - (int)gevent->y;
100 
101  // This is hacky. There is no plane with the right number in the other
102  // view, and the cell stagger confuses the coordinates.
103  const int other_newtotop = det_to_screen_y(plane+1, other_cell) + pixy/2;
104  *other_yoffset += other_newtotop - widg->allocation.height/2;
105 
106  // If we're back at the unzoomed view, clear offsets, even though this
107  // violates the "don't move the hit under the mouse pointer" rule.
108  // This lets the user find things again if they got lost panning the
109  // detector way off the screen and it is just generally satisfying to
110  // have the detector snap into place in an orderly way.
111  if(!zoomed())
112  screenxoffset = screenyoffset_yview = screenyoffset_xview = 0;
113 
114  redraw_event(NULL, NULL, NULL);
115 
116  return TRUE;
117 }
T max(const caf::Proxy< T > &a, T b)
gboolean redraw_event(__attribute__((unused)) GtkWidget *widg, __attribute__((unused)) GdkEventExpose *ee, __attribute__((unused)) gpointer data)
Definition: drawing.cxx:101
int pixx_from_pixy(const int y)
Definition: geo.cxx:51
Supply basic geometry functions.
int FDpixy
Definition: geo.cxx:14
void dopanning(const noe_view_t V, GdkEventMotion *gevent)
Definition: zoompan.cxx:31
const Var kY([](const caf::SRProxy *sr){float tmp=0.f;if(sr->mc.nu.empty()) return tmp;tmp=sr->mc.nu[0].y;return tmp;})
const XML_Char const XML_Char * data
Definition: expat.h:268
int NDpixx
Definition: geo.cxx:15
static int newbuttonpush
Definition: zoompan.cxx:20
bool isfd
Definition: geo.cxx:18
gboolean mousebuttonpress(__attribute__((unused)) GtkWidget *widg, GdkEventMotion *gevent, __attribute__((unused)) gpointer data)
Definition: zoompan.cxx:21
__attribute__((unused)) static std
static int yonbutton1
Definition: zoompan.cxx:19
int screenyoffset_yview
Definition: geo.cxx:98
std::vector< noeevent > theevents
Definition: noe_module.cc:28
int screenyoffset_xview
Definition: geo.cxx:98
int NDpixy
Definition: geo.cxx:15
static bool zoomed()
Definition: zoompan.cxx:50
int det_to_screen_y(const int plane, const int cell)
Definition: geo.cxx:119
int pixy
Definition: geo.cxx:24
#define TRUE
Definition: crcmodel.h:86
static int xonbutton1
Definition: zoompan.cxx:19
Definition: geo.h:1
int gevi
Definition: main.cxx:76
int screenxoffset
Definition: geo.cxx:98
int det_to_screen_x(const int plane)
Definition: geo.cxx:100
gboolean dozooming(GtkWidget *widg, GdkEventScroll *gevent, gpointer data)
Definition: zoompan.cxx:55
noe_view_t
Definition: geo.h:1
int screen_to_plane_unbounded(const noe_view_t view, const int x)
Definition: geo.cxx:182
int screen_to_cell_unbounded(const noe_view_t view, const int x, const int y)
Definition: geo.cxx:215
int pixx
Definition: geo.cxx:24
int FDpixx
Definition: geo.cxx:14