Mercurial > hg > orthanc-stone
comparison Samples/Sdl/BasicScene.cpp @ 700:059e1fd05fd6 refactor-viewport-controller
Introduced the ViewportController that sits between the application and the
Scene2D to handle the trackers and measuring tools. This is a work in progress.
The Scene2D is no longer an observable. Message sending is managed by the
ViewportController.
Move some refs to shared and weak to prevent lifetime issues.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Sun, 19 May 2019 16:26:17 +0200 |
parents | 462a5074f914 |
children | ef07304d4423 |
comparison
equal
deleted
inserted
replaced
699:5c551f078c18 | 700:059e1fd05fd6 |
---|---|
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" | 29 #include "../../Framework/Scene2D/Scene2D.h" |
30 #include "../../Framework/Scene2D/ZoomSceneTracker.h" | 30 #include "../../Framework/Scene2D/ZoomSceneTracker.h" |
31 #include "../../Framework/Scene2DViewport/ViewportController.h" | |
32 | |
31 #include "../../Framework/StoneInitialization.h" | 33 #include "../../Framework/StoneInitialization.h" |
32 #include "../../Framework/Messages/MessageBroker.h" | 34 #include "../../Framework/Messages/MessageBroker.h" |
33 | 35 |
34 // From Orthanc framework | 36 // From Orthanc framework |
35 #include <Core/Logging.h> | 37 #include <Core/Logging.h> |
42 #include <stdio.h> | 44 #include <stdio.h> |
43 | 45 |
44 static const unsigned int FONT_SIZE = 32; | 46 static const unsigned int FONT_SIZE = 32; |
45 static const int LAYER_POSITION = 150; | 47 static const int LAYER_POSITION = 150; |
46 | 48 |
47 | 49 using namespace OrthancStone; |
48 void PrepareScene(OrthancStone::Scene2D& scene) | 50 |
49 { | 51 void PrepareScene(ViewportControllerPtr controller) |
50 using namespace OrthancStone; | 52 { |
51 | 53 Scene2D& scene(*controller->GetScene()); |
52 // Texture of 2x2 size | 54 // Texture of 2x2 size |
53 { | 55 { |
54 Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); | 56 Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); |
55 | 57 |
56 uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0)); | 58 uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0)); |
135 } | 137 } |
136 } | 138 } |
137 | 139 |
138 | 140 |
139 void TakeScreenshot(const std::string& target, | 141 void TakeScreenshot(const std::string& target, |
140 const OrthancStone::Scene2D& scene, | 142 const Scene2D& scene, |
141 unsigned int canvasWidth, | 143 unsigned int canvasWidth, |
142 unsigned int canvasHeight) | 144 unsigned int canvasHeight) |
143 { | 145 { |
144 // Take a screenshot, then save it as PNG file | 146 // Take a screenshot, then save it as PNG file |
145 OrthancStone::CairoCompositor compositor(scene, canvasWidth, canvasHeight); | 147 CairoCompositor compositor(scene, canvasWidth, canvasHeight); |
146 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); | 148 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); |
147 compositor.Refresh(); | 149 compositor.Refresh(); |
148 | 150 |
149 Orthanc::ImageAccessor canvas; | 151 Orthanc::ImageAccessor canvas; |
150 compositor.GetCanvas().GetReadOnlyAccessor(canvas); | 152 compositor.GetCanvas().GetReadOnlyAccessor(canvas); |
155 Orthanc::PngWriter writer; | 157 Orthanc::PngWriter writer; |
156 writer.WriteToFile(target, png); | 158 writer.WriteToFile(target, png); |
157 } | 159 } |
158 | 160 |
159 | 161 |
160 void HandleApplicationEvent(OrthancStone::Scene2D& scene, | 162 void HandleApplicationEvent(ViewportControllerPtr controller, |
161 const OrthancStone::OpenGLCompositor& compositor, | 163 const OpenGLCompositor& compositor, |
162 const SDL_Event& event, | 164 const SDL_Event& event, |
163 std::auto_ptr<OrthancStone::IPointerTracker>& activeTracker) | 165 FlexiblePointerTrackerPtr& activeTracker) |
164 { | 166 { |
167 Scene2D& scene(*controller->GetScene()); | |
165 if (event.type == SDL_MOUSEMOTION) | 168 if (event.type == SDL_MOUSEMOTION) |
166 { | 169 { |
167 int scancodeCount = 0; | 170 int scancodeCount = 0; |
168 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); | 171 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); |
169 | 172 |
171 SDL_SCANCODE_LCTRL < scancodeCount && | 174 SDL_SCANCODE_LCTRL < scancodeCount && |
172 keyboardState[SDL_SCANCODE_LCTRL]) | 175 keyboardState[SDL_SCANCODE_LCTRL]) |
173 { | 176 { |
174 // The "left-ctrl" key is down, while no tracker is present | 177 // The "left-ctrl" key is down, while no tracker is present |
175 | 178 |
176 OrthancStone::PointerEvent e; | 179 PointerEvent e; |
177 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); | 180 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); |
178 | 181 |
179 OrthancStone::ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); | 182 ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); |
180 | 183 |
181 char buf[64]; | 184 char buf[64]; |
182 sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); | 185 sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); |
183 | 186 |
184 if (scene.HasLayer(LAYER_POSITION)) | 187 if (scene.HasLayer(LAYER_POSITION)) |
185 { | 188 { |
186 OrthancStone::TextSceneLayer& layer = | 189 TextSceneLayer& layer = |
187 dynamic_cast<OrthancStone::TextSceneLayer&>(scene.GetLayer(LAYER_POSITION)); | 190 dynamic_cast<TextSceneLayer&>(scene.GetLayer(LAYER_POSITION)); |
188 layer.SetText(buf); | 191 layer.SetText(buf); |
189 layer.SetPosition(p.GetX(), p.GetY()); | 192 layer.SetPosition(p.GetX(), p.GetY()); |
190 } | 193 } |
191 else | 194 else |
192 { | 195 { |
193 std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer); | 196 std::auto_ptr<TextSceneLayer> |
197 layer(new TextSceneLayer); | |
194 layer->SetColor(0, 255, 0); | 198 layer->SetColor(0, 255, 0); |
195 layer->SetText(buf); | 199 layer->SetText(buf); |
196 layer->SetBorder(20); | 200 layer->SetBorder(20); |
197 layer->SetAnchor(OrthancStone::BitmapAnchor_BottomCenter); | 201 layer->SetAnchor(BitmapAnchor_BottomCenter); |
198 layer->SetPosition(p.GetX(), p.GetY()); | 202 layer->SetPosition(p.GetX(), p.GetY()); |
199 scene.SetLayer(LAYER_POSITION, layer.release()); | 203 scene.SetLayer(LAYER_POSITION, layer.release()); |
200 } | 204 } |
201 } | 205 } |
202 else | 206 else |
204 scene.DeleteLayer(LAYER_POSITION); | 208 scene.DeleteLayer(LAYER_POSITION); |
205 } | 209 } |
206 } | 210 } |
207 else if (event.type == SDL_MOUSEBUTTONDOWN) | 211 else if (event.type == SDL_MOUSEBUTTONDOWN) |
208 { | 212 { |
209 OrthancStone::PointerEvent e; | 213 PointerEvent e; |
210 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); | 214 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); |
211 | 215 |
212 switch (event.button.button) | 216 switch (event.button.button) |
213 { | 217 { |
214 case SDL_BUTTON_MIDDLE: | 218 case SDL_BUTTON_MIDDLE: |
215 activeTracker.reset(new OrthancStone::PanSceneTracker(scene, e)); | 219 activeTracker.reset(new PanSceneTracker( |
220 controller, e)); | |
216 break; | 221 break; |
217 | 222 |
218 case SDL_BUTTON_RIGHT: | 223 case SDL_BUTTON_RIGHT: |
219 activeTracker.reset(new OrthancStone::ZoomSceneTracker(scene, e, | 224 activeTracker.reset(new ZoomSceneTracker( |
220 compositor.GetCanvasHeight())); | 225 controller, e, compositor.GetCanvasHeight())); |
221 break; | 226 break; |
222 | 227 |
223 case SDL_BUTTON_LEFT: | 228 case SDL_BUTTON_LEFT: |
224 activeTracker.reset(new OrthancStone::RotateSceneTracker(scene, e)); | 229 activeTracker.reset(new RotateSceneTracker( |
230 controller, e)); | |
225 break; | 231 break; |
226 | 232 |
227 default: | 233 default: |
228 break; | 234 break; |
229 } | 235 } |
267 type, severity, message ); | 273 type, severity, message ); |
268 } | 274 } |
269 } | 275 } |
270 | 276 |
271 | 277 |
272 void Run(OrthancStone::Scene2D& scene) | 278 void Run(ViewportControllerPtr controller) |
273 { | 279 { |
274 OrthancStone::SdlOpenGLWindow window("Hello", 1024, 768); | 280 SdlOpenGLWindow window("Hello", 1024, 768); |
275 | 281 |
276 scene.FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); | 282 controller->GetScene()->FitContent( |
283 window.GetCanvasWidth(), window.GetCanvasHeight()); | |
277 | 284 |
278 glEnable(GL_DEBUG_OUTPUT); | 285 glEnable(GL_DEBUG_OUTPUT); |
279 glDebugMessageCallback(OpenGLMessageCallback, 0); | 286 glDebugMessageCallback(OpenGLMessageCallback, 0); |
280 | 287 |
281 OrthancStone::OpenGLCompositor compositor(window, scene); | 288 OpenGLCompositor compositor(window, *controller->GetScene()); |
282 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, | 289 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, |
283 FONT_SIZE, Orthanc::Encoding_Latin1); | 290 FONT_SIZE, Orthanc::Encoding_Latin1); |
284 | 291 |
285 std::auto_ptr<OrthancStone::IPointerTracker> tracker; | 292 FlexiblePointerTrackerPtr tracker; |
286 | 293 |
287 bool stop = false; | 294 bool stop = false; |
288 while (!stop) | 295 while (!stop) |
289 { | 296 { |
290 compositor.Refresh(); | 297 compositor.Refresh(); |
298 stop = true; | 305 stop = true; |
299 break; | 306 break; |
300 } | 307 } |
301 else if (event.type == SDL_MOUSEMOTION) | 308 else if (event.type == SDL_MOUSEMOTION) |
302 { | 309 { |
303 if (tracker.get() != NULL) | 310 if (tracker) |
304 { | 311 { |
305 OrthancStone::PointerEvent e; | 312 PointerEvent e; |
306 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); | 313 e.AddPosition(compositor.GetPixelCenterCoordinates( |
307 tracker->Update(e); | 314 event.button.x, event.button.y)); |
315 tracker->PointerMove(e); | |
308 } | 316 } |
309 } | 317 } |
310 else if (event.type == SDL_MOUSEBUTTONUP) | 318 else if (event.type == SDL_MOUSEBUTTONUP) |
311 { | 319 { |
312 if (tracker.get() != NULL) | 320 if (tracker) |
313 { | 321 { |
314 tracker->Release(); | 322 PointerEvent e; |
315 tracker.reset(NULL); | 323 e.AddPosition(compositor.GetPixelCenterCoordinates( |
324 event.button.x, event.button.y)); | |
325 tracker->PointerUp(e); | |
326 if(!tracker->IsAlive()) | |
327 tracker = NULL; | |
316 } | 328 } |
317 } | 329 } |
318 else if (event.type == SDL_WINDOWEVENT && | 330 else if (event.type == SDL_WINDOWEVENT && |
319 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) | 331 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) |
320 { | 332 { |
321 tracker.reset(NULL); | 333 tracker = NULL; |
322 compositor.UpdateSize(); | 334 compositor.UpdateSize(); |
323 } | 335 } |
324 else if (event.type == SDL_KEYDOWN && | 336 else if (event.type == SDL_KEYDOWN && |
325 event.key.repeat == 0 /* Ignore key bounce */) | 337 event.key.repeat == 0 /* Ignore key bounce */) |
326 { | 338 { |
337 default: | 349 default: |
338 break; | 350 break; |
339 } | 351 } |
340 } | 352 } |
341 | 353 |
342 HandleApplicationEvent(scene, compositor, event, tracker); | 354 HandleApplicationEvent(controller, compositor, event, tracker); |
343 } | 355 } |
344 | 356 |
345 SDL_Delay(1); | 357 SDL_Delay(1); |
346 } | 358 } |
347 } | 359 } |
354 * Windows. Otherwise, one gets the linking error "undefined reference | 366 * Windows. Otherwise, one gets the linking error "undefined reference |
355 * to `SDL_main'". https://wiki.libsdl.org/FAQWindows | 367 * to `SDL_main'". https://wiki.libsdl.org/FAQWindows |
356 **/ | 368 **/ |
357 int main(int argc, char* argv[]) | 369 int main(int argc, char* argv[]) |
358 { | 370 { |
359 OrthancStone::StoneInitialize(); | 371 StoneInitialize(); |
360 Orthanc::Logging::EnableInfoLevel(true); | 372 Orthanc::Logging::EnableInfoLevel(true); |
361 | 373 |
362 try | 374 try |
363 { | 375 { |
364 OrthancStone::MessageBroker broker; | 376 MessageBroker broker; |
365 OrthancStone::Scene2D scene(broker); | 377 ViewportControllerPtr controller( |
366 PrepareScene(scene); | 378 new ViewportController(broker)); |
367 Run(scene); | 379 PrepareScene(controller); |
380 Run(controller); | |
368 } | 381 } |
369 catch (Orthanc::OrthancException& e) | 382 catch (Orthanc::OrthancException& e) |
370 { | 383 { |
371 LOG(ERROR) << "EXCEPTION: " << e.What(); | 384 LOG(ERROR) << "EXCEPTION: " << e.What(); |
372 } | 385 } |
373 | 386 |
374 OrthancStone::StoneFinalize(); | 387 StoneFinalize(); |
375 | 388 |
376 return 0; | 389 return 0; |
377 } | 390 } |