comparison Samples/Sdl/TrackerSampleApp.cpp @ 656:002d9562c8f5

Added support to DISABLE legacy scaling in SDL Windows (only in WIN32... this might also be needed on macos and GNU/Linux ?) + fixed text info overlay pos for angle measure (this requires the app to be aware of the compositor)
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 14 May 2019 16:54:13 +0200
parents 462a5074f914
children cb3b76d16234
comparison
equal deleted inserted replaced
655:1e26bb5f2a02 656:002d9562c8f5
78 if (currentTool_ == GuiTool_LAST) 78 if (currentTool_ == GuiTool_LAST)
79 currentTool_ = static_cast<GuiTool>(0);; 79 currentTool_ = static_cast<GuiTool>(0);;
80 printf("Current tool is now: %s\n", MeasureToolToString(currentTool_)); 80 printf("Current tool is now: %s\n", MeasureToolToString(currentTool_));
81 } 81 }
82 82
83 void TrackerSampleApp::DisplayInfoText(const PointerEvent& e) 83 void TrackerSampleApp::DisplayInfoText()
84 {
85 char buf[256];
86 sprintf(buf, "INFO TEXT\n*** INFO TEXT ***\ntoto tata tutu titi\nprrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrout");
87
88 TextSceneLayer* layerP = NULL;
89 if (scene_.HasLayer(FIXED_INFOTEXT_LAYER_ZINDEX))
90 {
91 TextSceneLayer& layer = dynamic_cast<TextSceneLayer&>(
92 scene_.GetLayer(FIXED_INFOTEXT_LAYER_ZINDEX));
93 layerP = &layer;
94 }
95 else
96 {
97 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer);
98 layerP = layer.get();
99 layer->SetColor(0, 255, 0);
100 layer->SetFontIndex(1);
101 layer->SetText(buf);
102 layer->SetBorder(20);
103 layer->SetAnchor(BitmapAnchor_TopLeft);
104 //layer->SetPosition(0,0);
105 scene_.SetLayer(FIXED_INFOTEXT_LAYER_ZINDEX, layer.release());
106 }
107 // position the fixed info text in the upper right corner
108 layerP->SetText(buf);
109 double cX = compositor_->GetCanvasWidth() * (-0.5);
110 double cY = compositor_->GetCanvasHeight() * (-0.5);
111 scene_.GetCanvasToSceneTransform().Apply(cX,cY);
112 layerP->SetPosition(cX, cY);
113 }
114
115 void TrackerSampleApp::DisplayFloatingCtrlInfoText(const PointerEvent& e)
84 { 116 {
85 ScenePoint2D p = e.GetMainPosition().Apply(scene_.GetCanvasToSceneTransform()); 117 ScenePoint2D p = e.GetMainPosition().Apply(scene_.GetCanvasToSceneTransform());
86 118
87 char buf[64]; 119 char buf[128];
88 sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); 120 sprintf(buf, "S:(%0.02f,%0.02f) C:(%0.02f,%0.02f)",
89 121 p.GetX(), p.GetY(),
90 if (scene_.HasLayer(INFOTEXT_LAYER_ZINDEX)) 122 e.GetMainPosition().GetX(), e.GetMainPosition().GetY());
123
124 if (scene_.HasLayer(FLOATING_INFOTEXT_LAYER_ZINDEX))
91 { 125 {
92 TextSceneLayer& layer = 126 TextSceneLayer& layer =
93 dynamic_cast<TextSceneLayer&>(scene_.GetLayer(INFOTEXT_LAYER_ZINDEX)); 127 dynamic_cast<TextSceneLayer&>(scene_.GetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX));
94 layer.SetText(buf); 128 layer.SetText(buf);
95 layer.SetPosition(p.GetX(), p.GetY()); 129 layer.SetPosition(p.GetX(), p.GetY());
96 } 130 }
97 else 131 else
98 { 132 {
100 layer->SetColor(0, 255, 0); 134 layer->SetColor(0, 255, 0);
101 layer->SetText(buf); 135 layer->SetText(buf);
102 layer->SetBorder(20); 136 layer->SetBorder(20);
103 layer->SetAnchor(BitmapAnchor_BottomCenter); 137 layer->SetAnchor(BitmapAnchor_BottomCenter);
104 layer->SetPosition(p.GetX(), p.GetY()); 138 layer->SetPosition(p.GetX(), p.GetY());
105 scene_.SetLayer(INFOTEXT_LAYER_ZINDEX, layer.release()); 139 scene_.SetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX, layer.release());
106 } 140 }
107 } 141 }
108 142
109 void TrackerSampleApp::HideInfoText() 143 void TrackerSampleApp::HideInfoText()
110 { 144 {
111 scene_.DeleteLayer(INFOTEXT_LAYER_ZINDEX); 145 scene_.DeleteLayer(FLOATING_INFOTEXT_LAYER_ZINDEX);
112 } 146 }
113 147
114 void TrackerSampleApp::HandleApplicationEvent( 148 void TrackerSampleApp::HandleApplicationEvent(
115 const OpenGLCompositor & compositor,
116 const SDL_Event & event) 149 const SDL_Event & event)
117 { 150 {
151 DisplayInfoText();
152
118 if (event.type == SDL_MOUSEMOTION) 153 if (event.type == SDL_MOUSEMOTION)
119 { 154 {
120 int scancodeCount = 0; 155 int scancodeCount = 0;
121 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); 156 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
122 157
125 keyboardState[SDL_SCANCODE_LCTRL]) 160 keyboardState[SDL_SCANCODE_LCTRL])
126 { 161 {
127 // The "left-ctrl" key is down, while no tracker is present 162 // The "left-ctrl" key is down, while no tracker is present
128 // Let's display the info text 163 // Let's display the info text
129 PointerEvent e; 164 PointerEvent e;
130 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); 165 e.AddPosition(compositor_->GetPixelCenterCoordinates(
131 DisplayInfoText(e); 166 event.button.x, event.button.y));
167
168 DisplayFloatingCtrlInfoText(e);
132 } 169 }
133 else 170 else
134 { 171 {
135 HideInfoText(); 172 HideInfoText();
136 //LOG(TRACE) << "(event.type == SDL_MOUSEMOTION)"; 173 //LOG(TRACE) << "(event.type == SDL_MOUSEMOTION)";
137 if (activeTracker_.get() != NULL) 174 if (activeTracker_.get() != NULL)
138 { 175 {
139 //LOG(TRACE) << "(activeTracker_.get() != NULL)"; 176 //LOG(TRACE) << "(activeTracker_.get() != NULL)";
140 PointerEvent e; 177 PointerEvent e;
141 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); 178 e.AddPosition(compositor_->GetPixelCenterCoordinates(
179 event.button.x, event.button.y));
180
142 //LOG(TRACE) << "event.button.x = " << event.button.x << " " << 181 //LOG(TRACE) << "event.button.x = " << event.button.x << " " <<
143 // "event.button.y = " << event.button.y; 182 // "event.button.y = " << event.button.y;
144 //LOG(TRACE) << "activeTracker_->PointerMove(e); " << 183 //LOG(TRACE) << "activeTracker_->PointerMove(e); " <<
145 // e.GetMainPosition().GetX() << " " << e.GetMainPosition().GetY(); 184 // e.GetMainPosition().GetX() << " " << e.GetMainPosition().GetY();
185
146 activeTracker_->PointerMove(e); 186 activeTracker_->PointerMove(e);
147 if (!activeTracker_->IsActive()) 187 if (!activeTracker_->IsActive())
148 activeTracker_ = NULL; 188 activeTracker_ = NULL;
149 } 189 }
150 } 190 }
152 else if (event.type == SDL_MOUSEBUTTONUP) 192 else if (event.type == SDL_MOUSEBUTTONUP)
153 { 193 {
154 if (activeTracker_) 194 if (activeTracker_)
155 { 195 {
156 PointerEvent e; 196 PointerEvent e;
157 e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); 197 e.AddPosition(compositor_->GetPixelCenterCoordinates(event.button.x, event.button.y));
158 activeTracker_->PointerUp(e); 198 activeTracker_->PointerUp(e);
159 if (!activeTracker_->IsActive()) 199 if (!activeTracker_->IsActive())
160 activeTracker_ = NULL; 200 activeTracker_ = NULL;
161 } 201 }
162 } 202 }
163 else if (event.type == SDL_MOUSEBUTTONDOWN) 203 else if (event.type == SDL_MOUSEBUTTONDOWN)
164 { 204 {
165 PointerEvent e; 205 PointerEvent e;
166 e.AddPosition(compositor.GetPixelCenterCoordinates( 206 e.AddPosition(compositor_->GetPixelCenterCoordinates(
167 event.button.x, event.button.y)); 207 event.button.x, event.button.y));
168 if (activeTracker_) 208 if (activeTracker_)
169 { 209 {
170 activeTracker_->PointerDown(e); 210 activeTracker_->PointerDown(e);
171 if (!activeTracker_->IsActive()) 211 if (!activeTracker_->IsActive())
172 activeTracker_ = NULL; 212 activeTracker_ = NULL;
173 } 213 }
174 else 214 else
175 { 215 {
176 // we ATTEMPT to create a tracker if need be 216 // we ATTEMPT to create a tracker if need be
177 activeTracker_ = CreateSuitableTracker(event, e, compositor); 217 activeTracker_ = CreateSuitableTracker(event, e);
178 } 218 }
179 } 219 }
180 else if (event.type == SDL_KEYDOWN && 220 else if (event.type == SDL_KEYDOWN &&
181 event.key.repeat == 0 /* Ignore key bounce */) 221 event.key.repeat == 0 /* Ignore key bounce */)
182 { 222 {
200 " is taking place"; 240 " is taking place";
201 } 241 }
202 break; 242 break;
203 243
204 case SDLK_s: 244 case SDLK_s:
205 scene_.FitContent(compositor.GetCanvasWidth(), 245 scene_.FitContent(compositor_->GetCanvasWidth(),
206 compositor.GetCanvasHeight()); 246 compositor_->GetCanvasHeight());
207 break; 247 break;
208 248
209 case SDLK_c: 249 case SDLK_c:
210 TakeScreenshot( 250 TakeScreenshot(
211 "screenshot.png", 251 "screenshot.png",
212 compositor.GetCanvasWidth(), 252 compositor_->GetCanvasWidth(),
213 compositor.GetCanvasHeight()); 253 compositor_->GetCanvasHeight());
214 break; 254 break;
215 255
216 default: 256 default:
217 break; 257 break;
218 } 258 }
219 } 259 }
220 } 260 }
221 261
262
263 void TrackerSampleApp::OnSceneTransformChanged(const Scene2D::SceneTransformChanged& message)
264 {
265 // do not try to call this too early!
266 if(compositor_.get() != NULL)
267 DisplayInfoText();
268 }
269
222 FlexiblePointerTrackerPtr TrackerSampleApp::CreateSuitableTracker( 270 FlexiblePointerTrackerPtr TrackerSampleApp::CreateSuitableTracker(
223 const SDL_Event & event, 271 const SDL_Event & event,
224 const PointerEvent & e, 272 const PointerEvent & e)
225 const OpenGLCompositor & compositor)
226 { 273 {
227 switch (event.button.button) 274 switch (event.button.button)
228 { 275 {
229 case SDL_BUTTON_MIDDLE: 276 case SDL_BUTTON_MIDDLE:
230 return CreateSimpleTrackerAdapter(PointerTrackerPtr( 277 return CreateSimpleTrackerAdapter(PointerTrackerPtr(
231 new PanSceneTracker(scene_, e))); 278 new PanSceneTracker(scene_, e)));
232 279
233 case SDL_BUTTON_RIGHT: 280 case SDL_BUTTON_RIGHT:
234 return CreateSimpleTrackerAdapter(PointerTrackerPtr( 281 return CreateSimpleTrackerAdapter(PointerTrackerPtr(
235 new ZoomSceneTracker(scene_, e, compositor.GetCanvasHeight()))); 282 new ZoomSceneTracker(scene_, e, compositor_->GetCanvasHeight())));
236 283
237 case SDL_BUTTON_LEFT: 284 case SDL_BUTTON_LEFT:
238 { 285 {
239 //LOG(TRACE) << "CreateSuitableTracker: case SDL_BUTTON_LEFT:"; 286 //LOG(TRACE) << "CreateSuitableTracker: case SDL_BUTTON_LEFT:";
240 // TODO: we need to iterate on the set of measuring tool and perform 287 // TODO: we need to iterate on the set of measuring tool and perform
262 case GuiTool_Pan: 309 case GuiTool_Pan:
263 return CreateSimpleTrackerAdapter(PointerTrackerPtr( 310 return CreateSimpleTrackerAdapter(PointerTrackerPtr(
264 new PanSceneTracker(scene_, e))); 311 new PanSceneTracker(scene_, e)));
265 case GuiTool_Zoom: 312 case GuiTool_Zoom:
266 return CreateSimpleTrackerAdapter(PointerTrackerPtr( 313 return CreateSimpleTrackerAdapter(PointerTrackerPtr(
267 new ZoomSceneTracker(scene_, e, compositor.GetCanvasHeight()))); 314 new ZoomSceneTracker(scene_, e, compositor_->GetCanvasHeight())));
268 //case GuiTool_AngleMeasure: 315 //case GuiTool_AngleMeasure:
269 // return new AngleMeasureTracker(scene_, measureTools_, undoStack_, e); 316 // return new AngleMeasureTracker(scene_, measureTools_, undoStack_, e);
270 //case GuiTool_CircleMeasure: 317 //case GuiTool_CircleMeasure:
271 // return new CircleMeasureTracker(scene_, measureTools_, undoStack_, e); 318 // return new CircleMeasureTracker(scene_, measureTools_, undoStack_, e);
272 //case GuiTool_EllipseMeasure: 319 //case GuiTool_EllipseMeasure:
395 442
396 void TrackerSampleApp::TakeScreenshot(const std::string& target, 443 void TrackerSampleApp::TakeScreenshot(const std::string& target,
397 unsigned int canvasWidth, 444 unsigned int canvasWidth,
398 unsigned int canvasHeight) 445 unsigned int canvasHeight)
399 { 446 {
400 // Take a screenshot, then save it as PNG file
401 CairoCompositor compositor(scene_, canvasWidth, canvasHeight); 447 CairoCompositor compositor(scene_, canvasWidth, canvasHeight);
402 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); 448 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE_0, Orthanc::Encoding_Latin1);
403 compositor.Refresh(); 449 compositor.Refresh();
404 450
405 Orthanc::ImageAccessor canvas; 451 Orthanc::ImageAccessor canvas;
406 compositor.GetCanvas().GetReadOnlyAccessor(canvas); 452 compositor.GetCanvas().GetReadOnlyAccessor(canvas);
407 453
417 { 463 {
418 // std::vector<MeasureToolPtr> measureTools_; 464 // std::vector<MeasureToolPtr> measureTools_;
419 return nullptr; 465 return nullptr;
420 } 466 }
421 467
468 static void GLAPIENTRY
469 OpenGLMessageCallback(GLenum source,
470 GLenum type,
471 GLuint id,
472 GLenum severity,
473 GLsizei length,
474 const GLchar* message,
475 const void* userParam)
476 {
477 if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
478 {
479 fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
480 (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
481 type, severity, message);
482 }
483 }
484
485 static bool g_stopApplication = false;
486
487 void TrackerSampleApp::Run()
488 {
489 // False means we do NOT let Windows treat this as a legacy application
490 // that needs to be scaled
491 SdlOpenGLWindow window("Hello", 1024, 1024, false);
492
493 GetScene().FitContent(window.GetCanvasWidth(), window.GetCanvasHeight());
494
495 glEnable(GL_DEBUG_OUTPUT);
496 glDebugMessageCallback(OpenGLMessageCallback, 0);
497
498 compositor_.reset(new OpenGLCompositor(window, GetScene()));
499
500 compositor_->SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
501 FONT_SIZE_0, Orthanc::Encoding_Latin1);
502 compositor_->SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT,
503 FONT_SIZE_1, Orthanc::Encoding_Latin1);
504
505 while (!g_stopApplication)
506 {
507 compositor_->Refresh();
508
509 SDL_Event event;
510 while (!g_stopApplication && SDL_PollEvent(&event))
511 {
512 if (event.type == SDL_QUIT)
513 {
514 g_stopApplication = true;
515 break;
516 }
517 else if (event.type == SDL_WINDOWEVENT &&
518 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
519 {
520 DisableTracker(); // was: tracker.reset(NULL);
521 compositor_->UpdateSize();
522 }
523 else if (event.type == SDL_KEYDOWN &&
524 event.key.repeat == 0 /* Ignore key bounce */)
525 {
526 switch (event.key.keysym.sym)
527 {
528 case SDLK_f:
529 window.GetWindow().ToggleMaximize();
530 break;
531
532 case SDLK_q:
533 g_stopApplication = true;
534 break;
535 default:
536 break;
537 }
538 }
539 HandleApplicationEvent(event);
540 }
541 SDL_Delay(1);
542 }
543 compositor_.reset(NULL);
544 }
545
422 546
423 547
424 } 548 }