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