Mercurial > hg > orthanc-stone
diff Samples/Sdl/RtViewer/RtViewerSdl.cpp @ 1406:5d7ee14dc1eb
Mouse wheel handler is now OK in SDL and Wasm
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Thu, 30 Apr 2020 00:25:55 +0200 |
parents | 3e644f6fadd4 |
children | 875c9a28236e |
line wrap: on
line diff
--- a/Samples/Sdl/RtViewer/RtViewerSdl.cpp Wed Apr 29 22:06:58 2020 +0200 +++ b/Samples/Sdl/RtViewer/RtViewerSdl.cpp Thu Apr 30 00:25:55 2020 +0200 @@ -182,16 +182,7 @@ StartLoaders(); - std::vector<boost::shared_ptr<SdlViewport>> sdlViewports; - for(size_t i = 0; i < views_.size(); ++i) - { - boost::shared_ptr<RtViewerView> view = views_[i]; - boost::shared_ptr<IViewport> viewport = view->GetViewport(); - boost::shared_ptr<SdlViewport> sdlViewport = - boost::dynamic_pointer_cast<SdlViewport>(viewport); - sdlViewports.push_back(sdlViewport); - } - OrthancStoneHelpers::SdlRunLoop(sdlViewports, interactor); + SdlRunLoop(views_, interactor); loadersContext->StopOracle(); } @@ -216,6 +207,179 @@ Orthanc::PngWriter writer; writer.WriteToFile(target, png); } + + static boost::shared_ptr<OrthancStone::RtViewerView> GetViewFromWindowId( + const std::vector<boost::shared_ptr<OrthancStone::RtViewerView> >& views, + Uint32 windowID) + { + using namespace OrthancStone; + for (size_t i = 0; i < views.size(); ++i) + { + boost::shared_ptr<OrthancStone::RtViewerView> view = views[i]; + boost::shared_ptr<IViewport> viewport = view->GetViewport(); + boost::shared_ptr<SdlViewport> sdlViewport = boost::dynamic_pointer_cast<SdlViewport>(viewport); + Uint32 curWindowID = sdlViewport->GetSdlWindowId(); + if (windowID == curWindowID) + return view; + } + return NULL; + } + + void RtViewerApp::SdlRunLoop(const std::vector<boost::shared_ptr<OrthancStone::RtViewerView> >& views, + OrthancStone::IViewportInteractor& interactor) + { + using namespace OrthancStone; + + // const std::vector<boost::shared_ptr<OrthancStone::RtViewerView> >& views + std::vector<boost::shared_ptr<OrthancStone::SdlViewport> > viewports; + for (size_t i = 0; i < views.size(); ++i) + { + boost::shared_ptr<RtViewerView> view = views[i]; + boost::shared_ptr<IViewport> viewport = view->GetViewport(); + boost::shared_ptr<SdlViewport> sdlViewport = + boost::dynamic_pointer_cast<SdlViewport>(viewport); + viewports.push_back(sdlViewport); + } + + { + int scancodeCount = 0; + const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); + + bool stop = false; + while (!stop) + { + bool paint = false; + SDL_Event event; + while (SDL_PollEvent(&event)) + { + if (event.type == SDL_QUIT) + { + stop = true; + break; + } + else if (event.type == SDL_WINDOWEVENT && + (event.window.event == SDL_WINDOWEVENT_RESIZED || + event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)) + { + boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( + views, event.window.windowID); + + boost::shared_ptr<SdlViewport> sdlViewport = + boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport()); + + sdlViewport->UpdateSize(event.window.data1, event.window.data2); + } + else if (event.type == SDL_WINDOWEVENT && + (event.window.event == SDL_WINDOWEVENT_SHOWN || + event.window.event == SDL_WINDOWEVENT_EXPOSED)) + { + boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( + views, event.window.windowID); + boost::shared_ptr<SdlViewport> sdlViewport = + boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport()); + sdlViewport->Paint(); + } + else if (event.type == SDL_KEYDOWN && + event.key.repeat == 0 /* Ignore key bounce */) + { + boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( + views, event.window.windowID); + + switch (event.key.keysym.sym) + { + case SDLK_f: + { + boost::shared_ptr<SdlViewport> sdlViewport = + boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport()); + sdlViewport->ToggleMaximize(); + } + break; + + case SDLK_s: + { + std::unique_ptr<OrthancStone::IViewport::ILock> lock(view->GetViewport()->Lock()); + lock->GetCompositor().FitContent(lock->GetController().GetScene()); + lock->Invalidate(); + } + break; + + case SDLK_q: + stop = true; + break; + + default: + break; + } + } + else if (event.type == SDL_MOUSEBUTTONDOWN || + event.type == SDL_MOUSEMOTION || + event.type == SDL_MOUSEBUTTONUP) + { + boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( + views, event.window.windowID); + + std::auto_ptr<OrthancStone::IViewport::ILock> lock(view->GetViewport()->Lock()); + if (lock->HasCompositor()) + { + OrthancStone::PointerEvent p; + OrthancStoneHelpers::GetPointerEvent(p, lock->GetCompositor(), + event, keyboardState, scancodeCount); + + switch (event.type) + { + case SDL_MOUSEBUTTONDOWN: + lock->GetController().HandleMousePress(interactor, p, + lock->GetCompositor().GetCanvasWidth(), + lock->GetCompositor().GetCanvasHeight()); + lock->Invalidate(); + break; + + case SDL_MOUSEMOTION: + if (lock->GetController().HandleMouseMove(p)) + { + lock->Invalidate(); + } + break; + + case SDL_MOUSEBUTTONUP: + lock->GetController().HandleMouseRelease(p); + lock->Invalidate(); + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + } + else if (event.type == SDL_MOUSEWHEEL) + { + boost::shared_ptr<RtViewerView> view = GetViewFromWindowId( + views, event.window.windowID); + + int delta = 0; + if (event.wheel.y < 0) + delta = -1; + if (event.wheel.y > 0) + delta = 1; + + view->Scroll(delta); + } + else + { + for (size_t i = 0; i < views.size(); ++i) + { + boost::shared_ptr<SdlViewport> sdlViewport = + boost::dynamic_pointer_cast<SdlViewport>(views[i]->GetViewport()); + if (sdlViewport->IsRefreshEvent(event)) + sdlViewport->Paint(); + } + } + } + } + // Small delay to avoid using 100% of CPU + SDL_Delay(1); + } + } } boost::weak_ptr<OrthancStone::RtViewerApp> g_app;