Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef toolx_Xt_zb_viewer 5 #define toolx_Xt_zb_viewer 6 7 #include "session" 8 #include "ImageArea" 9 #include "../X11/pixwin" 10 11 #include <X11/Shell.h> 12 #include <X11/StringDefs.h> 13 #include <X11/IntrinsicP.h> 14 15 #include <tools/sg/zb_viewer> 16 #include <tools/num2s> 17 #include <tools/sg/device_interactor> 18 #include <tools/sg/keys> 19 20 namespace toolx { 21 namespace Xt { 22 23 class zb_viewer: public tools::sg::zb_viewer { 24 typedef tools::sg::zb_viewer parent; 25 public: 26 zb_viewer(session& a_session, 27 int a_x = 0,int a_y = 0, 28 unsigned int a_width = 500,unsigned int a_height = 500, 29 const std::string& a_win_title = "") 30 :parent(a_session.out(),a_width,a_height) 31 ,m_session(a_session) 32 ,m_shell(0) 33 ,m_image_area(0) 34 ,m_pixwin(0) 35 ,m_interactor(0) 36 { 37 Widget app_widget = a_session.get_app_widget(); 38 if(!app_widget) return; 39 40 std::string sgeom; 41 tools::numas(a_width,sgeom); 42 sgeom += "x"; 43 tools::numas(a_height,sgeom); 44 sgeom += "+"; 45 tools::numas(a_x,sgeom); 46 sgeom += "+"; 47 tools::numas(a_y,sgeom); 48 49 Arg args[2]; 50 XtSetArg(args[0],XtNgeometry,XtNewString(sgeom.c_str())); 51 XtSetArg(args[1],XtNborderWidth,0); 52 53 m_shell = ::XtAppCreateShell((char*)a_win_title.c_str(), 54 (char*)"zb_viewer_shell", 55 topLevelShellWidgetClass,XtDisplay(app_widget),args,2); 56 ::XtSetMappedWhenManaged(m_shell,True); 57 58 m_image_area = ::XtCreateManagedWidget("imagearea",ImageArea::widget_class(),m_shell,args,0); 59 ::XtAddCallback(m_image_area,ImageArea::XoN_resizeCallback(),resize_cbk,(XtPointer)this); 60 ::XtAddCallback(m_image_area,ImageArea::XoN_paintCallback(),paint_cbk,(XtPointer)this); 61 ::XtAddCallback(m_image_area,ImageArea::XoN_eventCallback(),event_cbk,(XtPointer)this); 62 63 ::XtAddCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this); 64 65 ::XtRealizeWidget(m_shell); 66 67 {int iscreen; 68 Screen* screen = XtScreen(m_image_area); 69 iscreen = XScreenNumberOfScreen(screen); 70 m_pixwin = new toolx::X11::pixwin(a_session.out(),iscreen,XtDisplay(app_widget)); 71 m_pixwin->set_size(m_image_area->core.width,m_image_area->core.height);} 72 73 //Atom WM_DELETE_WINDOW_atom = ::XInternAtom(XtDisplay(m_shell),"WM_DELETE_WINDOW",False); 74 //::XSetWMProtocols(XtDisplay(m_shell),XtWindow(m_shell),&WM_DELETE_WINDOW_atom,1); 75 } 76 virtual ~zb_viewer() { 77 delete m_pixwin; 78 if(m_shell) { 79 ::XtRemoveCallback(m_image_area,ImageArea::XoN_paintCallback(),paint_cbk,(XtPointer)this); 80 ::XtRemoveCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this); 81 ::XtDestroyWidget(m_shell); 82 } 83 m_shell = 0; 84 m_image_area = 0; 85 } 86 protected: 87 zb_viewer(const zb_viewer& a_from) 88 :parent(a_from) 89 ,m_session(a_from.m_session) 90 ,m_shell(0) 91 ,m_image_area(0) 92 ,m_interactor(0) 93 {} 94 zb_viewer& operator=(const zb_viewer& a_from){ 95 parent::operator=(a_from); 96 return *this; 97 } 98 public: 99 bool has_window() const {return m_image_area?true:false;} 100 101 bool show() { 102 if(!m_shell) return false; 103 ::XtRealizeWidget(m_shell); 104 ::XtMapWidget(m_shell); 105 // Raise window : 106 if(XtIsWidget(m_shell) && XtIsRealized(m_shell) ) { 107 Display* display = XtDisplay(m_shell); 108 Atom atom = ::XInternAtom(display,"WM_DELETE_WINDOW",False); 109 ::XSetWMProtocols(display,XtWindow(m_shell),&atom,1); 110 ::XRaiseWindow(display,XtWindow(m_shell)); 111 } 112 return true; 113 } 114 115 void win_render() { 116 if(m_image_area) ImageArea::paint(m_image_area); 117 } 118 119 void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership. 120 protected: 121 static void resize_cbk(Widget a_widget,XtPointer a_tag,XtPointer){ 122 if(!XtIsRealized(a_widget)) return; 123 unsigned int width = a_widget->core.width; 124 unsigned int height = a_widget->core.height; 125 //::printf("debug: toolx::Xt::zb_viewer::resize_cbk: %d %d\n",width,height); 126 zb_viewer* _this = (zb_viewer*)a_tag; 127 _this->set_size(width,height); 128 _this->m_pixwin->set_size(width,height); 129 } 130 static void paint_cbk(Widget a_widget,XtPointer a_tag,XtPointer){ 131 if(!XtIsRealized(a_widget)) return; 132 unsigned int width = a_widget->core.width; 133 unsigned int height = a_widget->core.height; 134 //::printf("debug: toolx::Xt::zb_viewer::paint_cbk: %d %d\n",width,height); 135 zb_viewer* _this = (zb_viewer*)a_tag; 136 if(!_this->render(tools::sg::zb_viewer::get_rgbas,false)) return; //rgbas because Qt wants an image 32 bits aligned. 137 _this->m_pixwin->put_buffer(XtWindow(a_widget),width,height,tools::vec_data(_this->out_buffer())); 138 //parent::after_render(); 139 _this->out_buffer_clear(); 140 } 141 static void event_cbk(Widget,XtPointer a_tag,XtPointer a_data){ 142 zb_viewer* _this = (zb_viewer*)a_tag; 143 if(!_this->m_interactor) return; 144 ImageArea::XoAnyCallbackStruct* data = (ImageArea::XoAnyCallbackStruct*)a_data; 145 XEvent* xevent = data->event; 146 switch( xevent->type ) { 147 case KeyPress:{ 148 KeySym key_sym; 149 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL); 150 tools::sg::key_down_event event(_this->convert_key(key_sym)); 151 _this->m_interactor->key_press(event); 152 }return; 153 case KeyRelease:{ 154 KeySym key_sym; 155 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL); 156 tools::sg::key_up_event event(_this->convert_key(key_sym)); 157 _this->m_interactor->key_release(event); 158 }return; 159 case ButtonPress:{ 160 if(xevent->xbutton.button==Button4) { //4=wheel down, or move down double touch on trackpad = zoom in. 161 tools::sg::wheel_rotate_event event(8); //8=cooking. 162 _this->m_interactor->wheel_rotate(event); 163 } else if(xevent->xbutton.button==Button5) { //5=wheel up, or move up double touch on trackpad = zoom out. 164 tools::sg::wheel_rotate_event event(-8); //8=cooking. 165 _this->m_interactor->wheel_rotate(event); 166 } else if(xevent->xbutton.button==Button1) { 167 tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y); 168 _this->m_interactor->mouse_press(event); 169 } 170 }return; 171 case ButtonRelease:{ 172 if(xevent->xbutton.button==Button1) { 173 tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y); 174 _this->m_interactor->mouse_release(event); 175 } 176 }return; 177 case MotionNotify:{ 178 if((xevent->xmotion.state & Button1MotionMask)==Button1MotionMask) { 179 tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,0,0,false); 180 _this->m_interactor->mouse_move(event); 181 } 182 }return; 183 default:return;} 184 } 185 static void destroy_shell_callback(Widget,XtPointer a_tag,XtPointer) { 186 zb_viewer* _this = (zb_viewer*)a_tag; 187 _this->m_shell = 0; 188 _this->m_image_area = 0; 189 } 190 protected: 191 tools::key_code convert_key(KeySym a_key) { 192 if(a_key==XK_Shift_L) return tools::sg::key_shift(); 193 if(a_key==XK_Shift_R) return tools::sg::key_shift(); 194 return (tools::key_code)a_key; 195 } 196 protected: 197 session& m_session; 198 Widget m_shell; 199 Widget m_image_area; 200 toolx::X11::pixwin* m_pixwin; 201 tools::sg::device_interactor* m_interactor; 202 }; 203 204 }} 205 206 207 #endif 208