Mercurial > hg > orthanc-stone
comparison Samples/Sdl/RtViewer/RtViewerSdl.cpp @ 1392:ffdb82850e98
Sdl run loop in /Common (might revert if need to customize)
Segregation ongoing between sdl wasm
Both samples ok SDL msvc v141 x64
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Tue, 28 Apr 2020 13:52:21 +0200 |
parents | 5c83be3a6be5 |
children | 27e0a00bd3e8 |
comparison
equal
deleted
inserted
replaced
1391:32272ecfc6c2 | 1392:ffdb82850e98 |
---|---|
17 * You should have received a copy of the GNU Affero General Public License | 17 * You should have received a copy of the GNU Affero General Public License |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 **/ | 19 **/ |
20 | 20 |
21 #include "RtViewer.h" | 21 #include "RtViewer.h" |
22 #include "../SdlHelpers.h" | |
22 #include "SampleHelpers.h" | 23 #include "SampleHelpers.h" |
23 | 24 |
24 #include <Framework/StoneException.h> | 25 #include <Framework/StoneException.h> |
26 #include <Framework/StoneInitialization.h> | |
27 | |
28 #include <Framework/OpenGL/SdlOpenGLContext.h> | |
25 | 29 |
26 #include <boost/program_options.hpp> | 30 #include <boost/program_options.hpp> |
27 #include <SDL.h> | 31 #include <SDL.h> |
28 | 32 |
29 #include <string> | 33 #include <string> |
106 { | 110 { |
107 rtStructInstanceId_ = vm["rtstruct"].as<std::string>(); | 111 rtStructInstanceId_ = vm["rtstruct"].as<std::string>(); |
108 } | 112 } |
109 } | 113 } |
110 | 114 |
115 void RtViewerApp::RunSdl(int argc, char* argv[]) | |
116 { | |
117 ProcessOptions(argc, argv); | |
118 | |
119 { | |
120 std::unique_ptr<IViewport::ILock> lock(viewport_->Lock()); | |
121 ViewportController& controller = lock->GetController(); | |
122 Scene2D& scene = controller.GetScene(); | |
123 ICompositor& compositor = lock->GetCompositor(); | |
124 | |
125 // False means we do NOT let a hi-DPI aware desktop managedr treat this as a legacy application that requires | |
126 // scaling. | |
127 controller.FitContent(compositor.GetCanvasWidth(), compositor.GetCanvasHeight()); | |
128 | |
129 glEnable(GL_DEBUG_OUTPUT); | |
130 glDebugMessageCallback(OpenGLMessageCallback, 0); | |
131 | |
132 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, | |
133 FONT_SIZE_0, Orthanc::Encoding_Latin1); | |
134 compositor.SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT, | |
135 FONT_SIZE_1, Orthanc::Encoding_Latin1); | |
136 } | |
137 | |
138 /** | |
139 Create the shared loaders context | |
140 */ | |
141 loadersContext_.reset(new GenericLoadersContext(1, 4, 1)); | |
142 loadersContext_->StartOracle(); | |
143 | |
144 /** | |
145 It is very important that the Oracle (responsible for network I/O) be started before creating and firing the | |
146 loaders, for any command scheduled by the loader before the oracle is started will be lost. | |
147 */ | |
148 PrepareLoadersAndSlicers(); | |
149 | |
150 OrthancStone::DefaultViewportInteractor interactor; | |
151 | |
152 OrthancStoneHelpers::SdlRunLoop(viewport_, interactor); | |
153 | |
154 loadersContext_->StopOracle(); | |
155 } | |
156 | |
157 #if 0 | |
158 void RtViewerApp::HandleApplicationEvent( | |
159 const SDL_Event& event) | |
160 { | |
161 //DisplayInfoText(); | |
162 | |
163 std::unique_ptr<IViewport::ILock> lock(viewport_->Lock()); | |
164 ViewportController& controller = lock->GetController(); | |
165 Scene2D& scene = controller.GetScene(); | |
166 ICompositor& compositor = lock->GetCompositor(); | |
167 | |
168 if (event.type == SDL_MOUSEMOTION) | |
169 { | |
170 int scancodeCount = 0; | |
171 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); | |
172 | |
173 if (activeTracker_.get() == NULL && | |
174 SDL_SCANCODE_LALT < scancodeCount && | |
175 keyboardState[SDL_SCANCODE_LALT]) | |
176 { | |
177 // The "left-ctrl" key is down, while no tracker is present | |
178 // Let's display the info text | |
179 PointerEvent e; | |
180 e.AddPosition(compositor.GetPixelCenterCoordinates( | |
181 event.button.x, event.button.y)); | |
182 | |
183 DisplayFloatingCtrlInfoText(e); | |
184 } | |
185 else | |
186 { | |
187 HideInfoText(); | |
188 //LOG(TRACE) << "(event.type == SDL_MOUSEMOTION)"; | |
189 if (activeTracker_.get() != NULL) | |
190 { | |
191 //LOG(TRACE) << "(activeTracker_.get() != NULL)"; | |
192 PointerEvent e; | |
193 e.AddPosition(compositor.GetPixelCenterCoordinates( | |
194 event.button.x, event.button.y)); | |
195 | |
196 //LOG(TRACE) << "event.button.x = " << event.button.x << " " << | |
197 // "event.button.y = " << event.button.y; | |
198 LOG(TRACE) << "activeTracker_->PointerMove(e); " << | |
199 e.GetMainPosition().GetX() << " " << e.GetMainPosition().GetY(); | |
200 | |
201 activeTracker_->PointerMove(e); | |
202 if (!activeTracker_->IsAlive()) | |
203 activeTracker_.reset(); | |
204 } | |
205 } | |
206 } | |
207 else if (event.type == SDL_MOUSEBUTTONUP) | |
208 { | |
209 if (activeTracker_) | |
210 { | |
211 PointerEvent e; | |
212 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); | |
213 activeTracker_->PointerUp(e); | |
214 if (!activeTracker_->IsAlive()) | |
215 activeTracker_.reset(); | |
216 } | |
217 } | |
218 else if (event.type == SDL_MOUSEBUTTONDOWN) | |
219 { | |
220 PointerEvent e; | |
221 e.AddPosition(compositor.GetPixelCenterCoordinates( | |
222 event.button.x, event.button.y)); | |
223 if (activeTracker_) | |
224 { | |
225 activeTracker_->PointerDown(e); | |
226 if (!activeTracker_->IsAlive()) | |
227 activeTracker_.reset(); | |
228 } | |
229 else | |
230 { | |
231 // we ATTEMPT to create a tracker if need be | |
232 activeTracker_ = CreateSuitableTracker(event, e); | |
233 } | |
234 } | |
235 else if (event.type == SDL_KEYDOWN && | |
236 event.key.repeat == 0 /* Ignore key bounce */) | |
237 { | |
238 switch (event.key.keysym.sym) | |
239 { | |
240 case SDLK_ESCAPE: | |
241 if (activeTracker_) | |
242 { | |
243 activeTracker_->Cancel(); | |
244 if (!activeTracker_->IsAlive()) | |
245 activeTracker_.reset(); | |
246 } | |
247 break; | |
248 | |
249 case SDLK_r: | |
250 UpdateLayers(); | |
251 { | |
252 std::unique_ptr<IViewport::ILock> lock(viewport_->Lock()); | |
253 lock->Invalidate(); | |
254 } | |
255 break; | |
256 | |
257 case SDLK_s: | |
258 compositor.FitContent(scene); | |
259 break; | |
260 | |
261 case SDLK_t: | |
262 if (!activeTracker_) | |
263 SelectNextTool(); | |
264 else | |
265 { | |
266 LOG(WARNING) << "You cannot change the active tool when an interaction" | |
267 " is taking place"; | |
268 } | |
269 break; | |
270 | |
271 case SDLK_z: | |
272 LOG(TRACE) << "SDLK_z has been pressed. event.key.keysym.mod == " << event.key.keysym.mod; | |
273 if (event.key.keysym.mod & KMOD_CTRL) | |
274 { | |
275 if (controller.CanUndo()) | |
276 { | |
277 LOG(TRACE) << "Undoing..."; | |
278 controller.Undo(); | |
279 } | |
280 else | |
281 { | |
282 LOG(WARNING) << "Nothing to undo!!!"; | |
283 } | |
284 } | |
285 break; | |
286 | |
287 case SDLK_y: | |
288 LOG(TRACE) << "SDLK_y has been pressed. event.key.keysym.mod == " << event.key.keysym.mod; | |
289 if (event.key.keysym.mod & KMOD_CTRL) | |
290 { | |
291 if (controller.CanRedo()) | |
292 { | |
293 LOG(TRACE) << "Redoing..."; | |
294 controller.Redo(); | |
295 } | |
296 else | |
297 { | |
298 LOG(WARNING) << "Nothing to redo!!!"; | |
299 } | |
300 } | |
301 break; | |
302 | |
303 case SDLK_c: | |
304 TakeScreenshot( | |
305 "screenshot.png", | |
306 compositor.GetCanvasWidth(), | |
307 compositor.GetCanvasHeight()); | |
308 break; | |
309 | |
310 default: | |
311 break; | |
312 } | |
313 } | |
314 else if (viewport_->IsRefreshEvent(event)) | |
315 { | |
316 // the viewport has been invalidated and requires repaint | |
317 viewport_->Paint(); | |
318 } | |
319 } | |
320 #endif | |
321 | |
322 #if 0 | |
111 void RtViewerApp::RunSdl(int argc, char* argv[]) | 323 void RtViewerApp::RunSdl(int argc, char* argv[]) |
112 { | 324 { |
113 ProcessOptions(argc, argv); | 325 ProcessOptions(argc, argv); |
114 | 326 |
115 { | 327 { |
181 } | 393 } |
182 SDL_Delay(1); | 394 SDL_Delay(1); |
183 } | 395 } |
184 loadersContext_->StopOracle(); | 396 loadersContext_->StopOracle(); |
185 } | 397 } |
398 #endif | |
399 | |
400 #if 0 | |
401 boost::shared_ptr<IFlexiblePointerTracker> RtViewerApp::CreateSuitableTracker( | |
402 const SDL_Event& event, | |
403 const PointerEvent& e) | |
404 { | |
405 std::unique_ptr<IViewport::ILock> lock(viewport_->Lock()); | |
406 ViewportController& controller = lock->GetController(); | |
407 Scene2D& scene = controller.GetScene(); | |
408 ICompositor& compositor = lock->GetCompositor(); | |
409 | |
410 using namespace Orthanc; | |
411 | |
412 switch (event.button.button) | |
413 { | |
414 case SDL_BUTTON_MIDDLE: | |
415 return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker | |
416 (viewport_, e)); | |
417 | |
418 case SDL_BUTTON_RIGHT: | |
419 return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker | |
420 (viewport_, e, compositor.GetCanvasHeight())); | |
421 | |
422 case SDL_BUTTON_LEFT: | |
423 { | |
424 //LOG(TRACE) << "CreateSuitableTracker: case SDL_BUTTON_LEFT:"; | |
425 // TODO: we need to iterate on the set of measuring tool and perform | |
426 // a hit test to check if a tracker needs to be created for edition. | |
427 // Otherwise, depending upon the active tool, we might want to create | |
428 // a "measuring tool creation" tracker | |
429 | |
430 // TODO: if there are conflicts, we should prefer a tracker that | |
431 // pertains to the type of measuring tool currently selected (TBD?) | |
432 boost::shared_ptr<IFlexiblePointerTracker> hitTestTracker = TrackerHitTest(e); | |
433 | |
434 if (hitTestTracker != NULL) | |
435 { | |
436 //LOG(TRACE) << "hitTestTracker != NULL"; | |
437 return hitTestTracker; | |
438 } | |
439 else | |
440 { | |
441 switch (currentTool_) | |
442 { | |
443 case RtViewerGuiTool_Rotate: | |
444 //LOG(TRACE) << "Creating RotateSceneTracker"; | |
445 return boost::shared_ptr<IFlexiblePointerTracker>(new RotateSceneTracker(viewport_, e)); | |
446 case RtViewerGuiTool_Pan: | |
447 return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker(viewport_, e)); | |
448 case RtViewerGuiTool_Zoom: | |
449 return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker(viewport_, e, compositor.GetCanvasHeight())); | |
450 //case GuiTool_AngleMeasure: | |
451 // return new AngleMeasureTracker(GetScene(), e); | |
452 //case GuiTool_CircleMeasure: | |
453 // return new CircleMeasureTracker(GetScene(), e); | |
454 //case GuiTool_EllipseMeasure: | |
455 // return new EllipseMeasureTracker(GetScene(), e); | |
456 case RtViewerGuiTool_LineMeasure: | |
457 return boost::shared_ptr<IFlexiblePointerTracker>(new CreateLineMeasureTracker(viewport_, e)); | |
458 case RtViewerGuiTool_AngleMeasure: | |
459 return boost::shared_ptr<IFlexiblePointerTracker>(new CreateAngleMeasureTracker(viewport_, e)); | |
460 case RtViewerGuiTool_CircleMeasure: | |
461 LOG(ERROR) << "Not implemented yet!"; | |
462 return boost::shared_ptr<IFlexiblePointerTracker>(); | |
463 case RtViewerGuiTool_EllipseMeasure: | |
464 LOG(ERROR) << "Not implemented yet!"; | |
465 return boost::shared_ptr<IFlexiblePointerTracker>(); | |
466 default: | |
467 throw OrthancException(ErrorCode_InternalError, "Wrong tool!"); | |
468 } | |
469 } | |
470 } | |
471 default: | |
472 return boost::shared_ptr<IFlexiblePointerTracker>(); | |
473 } | |
474 } | |
475 #endif | |
476 | |
186 } | 477 } |
478 | |
479 boost::weak_ptr<OrthancStone::RtViewerApp> g_app; | |
480 | |
481 /** | |
482 * IMPORTANT: The full arguments to "main()" are needed for SDL on | |
483 * Windows. Otherwise, one gets the linking error "undefined reference | |
484 * to `SDL_main'". https://wiki.libsdl.org/FAQWindows | |
485 **/ | |
486 int main(int argc, char* argv[]) | |
487 { | |
488 using namespace OrthancStone; | |
489 | |
490 StoneInitialize(); | |
491 | |
492 try | |
493 { | |
494 boost::shared_ptr<RtViewerApp> app = RtViewerApp::Create(); | |
495 g_app = app; | |
496 app->RunSdl(argc,argv); | |
497 } | |
498 catch (Orthanc::OrthancException& e) | |
499 { | |
500 LOG(ERROR) << "EXCEPTION: " << e.What(); | |
501 } | |
502 | |
503 StoneFinalize(); | |
504 | |
505 return 0; | |
506 } | |
507 |