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 }