Mercurial > hg > orthanc-stone
comparison Samples/Sdl/BasicScene.cpp @ 891:0aff28f15ea2
new abstraction: IViewport
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 10 Jul 2019 18:18:42 +0200 |
parents | 77c96ba899f9 |
children | 9c2f6d6b9f4a 88bf49aebc13 |
comparison
equal
deleted
inserted
replaced
890:77c96ba899f9 | 891:0aff28f15ea2 |
---|---|
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 | 21 |
22 // From Stone | 22 // From Stone |
23 #include "../../Applications/Sdl/SdlOpenGLWindow.h" | 23 #include "../../Framework/Viewport/SdlViewport.h" |
24 #include "../../Framework/Scene2D/CairoCompositor.h" | 24 #include "../../Framework/Scene2D/CairoCompositor.h" |
25 #include "../../Framework/Scene2D/ColorTextureSceneLayer.h" | 25 #include "../../Framework/Scene2D/ColorTextureSceneLayer.h" |
26 #include "../../Framework/Scene2D/OpenGLCompositor.h" | 26 #include "../../Framework/Scene2D/OpenGLCompositor.h" |
27 #include "../../Framework/Scene2D/PanSceneTracker.h" | 27 #include "../../Framework/Scene2D/PanSceneTracker.h" |
28 #include "../../Framework/Scene2D/RotateSceneTracker.h" | 28 #include "../../Framework/Scene2D/RotateSceneTracker.h" |
29 #include "../../Framework/Scene2D/Scene2D.h" | |
30 #include "../../Framework/Scene2D/ZoomSceneTracker.h" | 29 #include "../../Framework/Scene2D/ZoomSceneTracker.h" |
31 #include "../../Framework/Scene2DViewport/ViewportController.h" | 30 #include "../../Framework/Scene2DViewport/ViewportController.h" |
32 #include "../../Framework/Scene2DViewport/UndoStack.h" | 31 #include "../../Framework/Scene2DViewport/UndoStack.h" |
33 | 32 |
34 #include "../../Framework/StoneInitialization.h" | 33 #include "../../Framework/StoneInitialization.h" |
40 #include <Core/Images/Image.h> | 39 #include <Core/Images/Image.h> |
41 #include <Core/Images/ImageProcessing.h> | 40 #include <Core/Images/ImageProcessing.h> |
42 #include <Core/Images/PngWriter.h> | 41 #include <Core/Images/PngWriter.h> |
43 | 42 |
44 #include <boost/make_shared.hpp> | 43 #include <boost/make_shared.hpp> |
45 #include <boost/ref.hpp> | |
46 | 44 |
47 #include <SDL.h> | 45 #include <SDL.h> |
48 #include <stdio.h> | 46 #include <stdio.h> |
49 | 47 |
50 static const unsigned int FONT_SIZE = 32; | 48 static const unsigned int FONT_SIZE = 32; |
51 static const int LAYER_POSITION = 150; | 49 static const int LAYER_POSITION = 150; |
52 | 50 |
53 void PrepareScene(boost::shared_ptr<OrthancStone::ViewportController> controller) | 51 |
52 void PrepareScene(OrthancStone::Scene2D& scene) | |
54 { | 53 { |
55 using namespace OrthancStone; | 54 using namespace OrthancStone; |
56 Scene2D& scene(*controller->GetScene()); | 55 |
57 // Texture of 2x2 size | 56 // Texture of 2x2 size |
58 { | 57 { |
59 Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); | 58 Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); |
60 | 59 |
61 uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0)); | 60 uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0)); |
160 Orthanc::PngWriter writer; | 159 Orthanc::PngWriter writer; |
161 writer.WriteToFile(target, png); | 160 writer.WriteToFile(target, png); |
162 } | 161 } |
163 | 162 |
164 | 163 |
165 void HandleApplicationEvent(boost::shared_ptr<OrthancStone::ViewportController> controller, | 164 void HandleApplicationEvent(const SDL_Event& event, |
166 const OrthancStone::OpenGLCompositor& compositor, | 165 boost::shared_ptr<OrthancStone::ViewportController>& controller, |
167 const SDL_Event& event, | |
168 boost::shared_ptr<OrthancStone::IFlexiblePointerTracker>& activeTracker) | 166 boost::shared_ptr<OrthancStone::IFlexiblePointerTracker>& activeTracker) |
169 { | 167 { |
170 using namespace OrthancStone; | 168 using namespace OrthancStone; |
171 Scene2D& scene(*controller->GetScene()); | 169 |
170 Scene2D& scene = controller->GetScene(); | |
171 IViewport& viewport = controller->GetViewport(); | |
172 | |
172 if (event.type == SDL_MOUSEMOTION) | 173 if (event.type == SDL_MOUSEMOTION) |
173 { | 174 { |
174 int scancodeCount = 0; | 175 int scancodeCount = 0; |
175 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); | 176 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); |
176 | 177 |
179 keyboardState[SDL_SCANCODE_LCTRL]) | 180 keyboardState[SDL_SCANCODE_LCTRL]) |
180 { | 181 { |
181 // The "left-ctrl" key is down, while no tracker is present | 182 // The "left-ctrl" key is down, while no tracker is present |
182 | 183 |
183 PointerEvent e; | 184 PointerEvent e; |
184 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); | 185 e.AddPosition(viewport.GetPixelCenterCoordinates(event.button.x, event.button.y)); |
185 | 186 |
186 ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); | 187 ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); |
187 | 188 |
188 char buf[64]; | 189 char buf[64]; |
189 sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); | 190 sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); |
213 } | 214 } |
214 } | 215 } |
215 else if (event.type == SDL_MOUSEBUTTONDOWN) | 216 else if (event.type == SDL_MOUSEBUTTONDOWN) |
216 { | 217 { |
217 PointerEvent e; | 218 PointerEvent e; |
218 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); | 219 e.AddPosition(viewport.GetPixelCenterCoordinates(event.button.x, event.button.y)); |
219 | 220 |
220 switch (event.button.button) | 221 switch (event.button.button) |
221 { | 222 { |
222 case SDL_BUTTON_MIDDLE: | 223 case SDL_BUTTON_MIDDLE: |
223 activeTracker = boost::make_shared<PanSceneTracker>(controller, e); | 224 activeTracker = boost::make_shared<PanSceneTracker>(controller, e); |
224 break; | 225 break; |
225 | 226 |
226 case SDL_BUTTON_RIGHT: | 227 case SDL_BUTTON_RIGHT: |
227 activeTracker = boost::make_shared<ZoomSceneTracker>(controller, | 228 activeTracker = boost::make_shared<ZoomSceneTracker> |
228 e, compositor.GetCanvasHeight()); | 229 (controller, e, viewport.GetCanvasHeight()); |
229 break; | 230 break; |
230 | 231 |
231 case SDL_BUTTON_LEFT: | 232 case SDL_BUTTON_LEFT: |
232 activeTracker = boost::make_shared<RotateSceneTracker>(controller, e); | 233 activeTracker = boost::make_shared<RotateSceneTracker>(controller, e); |
233 break; | 234 break; |
240 event.key.repeat == 0 /* Ignore key bounce */) | 241 event.key.repeat == 0 /* Ignore key bounce */) |
241 { | 242 { |
242 switch (event.key.keysym.sym) | 243 switch (event.key.keysym.sym) |
243 { | 244 { |
244 case SDLK_s: | 245 case SDLK_s: |
245 controller->FitContent(compositor.GetCanvasWidth(), | 246 controller->FitContent(viewport.GetCanvasWidth(), |
246 compositor.GetCanvasHeight()); | 247 viewport.GetCanvasHeight()); |
247 break; | 248 break; |
248 | 249 |
249 case SDLK_c: | 250 case SDLK_c: |
250 TakeScreenshot("screenshot.png", scene, | 251 TakeScreenshot("screenshot.png", scene, |
251 compositor.GetCanvasWidth(), | 252 viewport.GetCanvasWidth(), |
252 compositor.GetCanvasHeight()); | 253 viewport.GetCanvasHeight()); |
253 break; | 254 break; |
254 | 255 |
255 default: | 256 default: |
256 break; | 257 break; |
257 } | 258 } |
275 type, severity, message ); | 276 type, severity, message ); |
276 } | 277 } |
277 } | 278 } |
278 | 279 |
279 | 280 |
280 void Run(boost::shared_ptr<OrthancStone::ViewportController> controller) | 281 void Run(OrthancStone::MessageBroker& broker, |
282 OrthancStone::SdlViewport& viewport) | |
281 { | 283 { |
282 using namespace OrthancStone; | 284 using namespace OrthancStone; |
283 SdlOpenGLWindow window("Hello", 1024, 768); | 285 |
284 | 286 boost::shared_ptr<ViewportController> controller( |
285 controller->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); | 287 new ViewportController(boost::make_shared<UndoStack>(), broker, viewport)); |
286 | 288 |
287 glEnable(GL_DEBUG_OUTPUT); | 289 glEnable(GL_DEBUG_OUTPUT); |
288 glDebugMessageCallback(OpenGLMessageCallback, 0); | 290 glDebugMessageCallback(OpenGLMessageCallback, 0); |
289 | 291 |
290 OpenGLCompositor compositor(window, *controller->GetScene()); | |
291 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, | |
292 FONT_SIZE, Orthanc::Encoding_Latin1); | |
293 | |
294 boost::shared_ptr<IFlexiblePointerTracker> tracker; | 292 boost::shared_ptr<IFlexiblePointerTracker> tracker; |
295 | 293 |
294 bool firstShown = true; | |
296 bool stop = false; | 295 bool stop = false; |
297 while (!stop) | 296 while (!stop) |
298 { | 297 { |
299 compositor.Refresh(); | 298 viewport.Refresh(); |
300 | 299 |
301 SDL_Event event; | 300 SDL_Event event; |
302 while (!stop && | 301 while (!stop && |
303 SDL_PollEvent(&event)) | 302 SDL_PollEvent(&event)) |
304 { | 303 { |
310 else if (event.type == SDL_MOUSEMOTION) | 309 else if (event.type == SDL_MOUSEMOTION) |
311 { | 310 { |
312 if (tracker) | 311 if (tracker) |
313 { | 312 { |
314 PointerEvent e; | 313 PointerEvent e; |
315 e.AddPosition(compositor.GetPixelCenterCoordinates( | 314 e.AddPosition(viewport.GetPixelCenterCoordinates( |
316 event.button.x, event.button.y)); | 315 event.button.x, event.button.y)); |
317 tracker->PointerMove(e); | 316 tracker->PointerMove(e); |
318 } | 317 } |
319 } | 318 } |
320 else if (event.type == SDL_MOUSEBUTTONUP) | 319 else if (event.type == SDL_MOUSEBUTTONUP) |
321 { | 320 { |
322 if (tracker) | 321 if (tracker) |
323 { | 322 { |
324 PointerEvent e; | 323 PointerEvent e; |
325 e.AddPosition(compositor.GetPixelCenterCoordinates( | 324 e.AddPosition(viewport.GetPixelCenterCoordinates( |
326 event.button.x, event.button.y)); | 325 event.button.x, event.button.y)); |
327 tracker->PointerUp(e); | 326 tracker->PointerUp(e); |
328 if(!tracker->IsAlive()) | 327 if(!tracker->IsAlive()) |
329 tracker.reset(); | 328 tracker.reset(); |
330 } | 329 } |
331 } | 330 } |
332 else if (event.type == SDL_WINDOWEVENT && | 331 else if (event.type == SDL_WINDOWEVENT) |
333 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) | 332 { |
334 { | 333 switch (event.window.event) |
335 tracker.reset(); | 334 { |
335 case SDL_WINDOWEVENT_SIZE_CHANGED: | |
336 tracker.reset(); | |
337 break; | |
338 | |
339 case SDL_WINDOWEVENT_SHOWN: | |
340 if (firstShown) | |
341 { | |
342 // Once the window is first shown, fit the content to its size | |
343 controller->FitContent(viewport.GetCanvasWidth(), viewport.GetCanvasHeight()); | |
344 firstShown = false; | |
345 } | |
346 | |
347 break; | |
348 | |
349 default: | |
350 break; | |
351 } | |
336 } | 352 } |
337 else if (event.type == SDL_KEYDOWN && | 353 else if (event.type == SDL_KEYDOWN && |
338 event.key.repeat == 0 /* Ignore key bounce */) | 354 event.key.repeat == 0 /* Ignore key bounce */) |
339 { | 355 { |
340 switch (event.key.keysym.sym) | 356 switch (event.key.keysym.sym) |
341 { | 357 { |
342 case SDLK_f: | 358 case SDLK_f: |
343 window.GetWindow().ToggleMaximize(); | 359 viewport.GetContext().GetWindow().ToggleMaximize(); |
344 break; | 360 break; |
345 | 361 |
346 case SDLK_q: | 362 case SDLK_q: |
347 stop = true; | 363 stop = true; |
348 break; | 364 break; |
350 default: | 366 default: |
351 break; | 367 break; |
352 } | 368 } |
353 } | 369 } |
354 | 370 |
355 HandleApplicationEvent(controller, compositor, event, tracker); | 371 HandleApplicationEvent(event, controller, tracker); |
356 } | 372 } |
357 | 373 |
358 SDL_Delay(1); | 374 SDL_Delay(1); |
359 } | 375 } |
360 } | 376 } |
367 * Windows. Otherwise, one gets the linking error "undefined reference | 383 * Windows. Otherwise, one gets the linking error "undefined reference |
368 * to `SDL_main'". https://wiki.libsdl.org/FAQWindows | 384 * to `SDL_main'". https://wiki.libsdl.org/FAQWindows |
369 **/ | 385 **/ |
370 int main(int argc, char* argv[]) | 386 int main(int argc, char* argv[]) |
371 { | 387 { |
372 using namespace OrthancStone; | 388 OrthancStone::StoneInitialize(); |
373 StoneInitialize(); | |
374 Orthanc::Logging::EnableInfoLevel(true); | 389 Orthanc::Logging::EnableInfoLevel(true); |
375 | 390 |
376 try | 391 try |
377 { | 392 { |
378 MessageBroker broker; | 393 OrthancStone::SdlViewport viewport("Hello", 1024, 768); |
379 boost::shared_ptr<UndoStack> undoStack(new UndoStack); | 394 PrepareScene(viewport.GetScene()); |
380 boost::shared_ptr<ViewportController> controller = boost::make_shared<ViewportController>( | 395 |
381 undoStack, boost::ref(broker)); | 396 viewport.GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, |
382 PrepareScene(controller); | 397 FONT_SIZE, Orthanc::Encoding_Latin1); |
383 Run(controller); | 398 |
399 OrthancStone::MessageBroker broker; | |
400 Run(broker, viewport); | |
384 } | 401 } |
385 catch (Orthanc::OrthancException& e) | 402 catch (Orthanc::OrthancException& e) |
386 { | 403 { |
387 LOG(ERROR) << "EXCEPTION: " << e.What(); | 404 LOG(ERROR) << "EXCEPTION: " << e.What(); |
388 } | 405 } |
389 | 406 |
390 StoneFinalize(); | 407 OrthancStone::StoneFinalize(); |
391 | 408 |
392 return 0; | 409 return 0; |
393 } | 410 } |