Mercurial > hg > orthanc-stone
comparison Samples/Sdl/SimpleViewer/SdlSimpleViewer.cpp @ 1368:33da5d02885f broker
SdlSimpleViewer rename
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Sat, 18 Apr 2020 14:45:22 +0200 |
parents | |
children | 9d138883be66 |
comparison
equal
deleted
inserted
replaced
1367:fd2d848c0d6d | 1368:33da5d02885f |
---|---|
1 | |
2 #include "SdlSimpleViewerApplication.h" | |
3 | |
4 #include <Core/OrthancException.h> | |
5 | |
6 #include <Framework/Loaders/GenericLoadersContext.h> | |
7 #include <Framework/StoneException.h> | |
8 #include <Framework/StoneEnumerations.h> | |
9 #include <Framework/StoneInitialization.h> | |
10 #include <Framework/Viewport/SdlViewport.h> | |
11 | |
12 #include <SDL.h> | |
13 | |
14 namespace OrthancStone | |
15 { | |
16 static KeyboardModifiers GetKeyboardModifiers(const uint8_t* keyboardState, | |
17 const int scancodeCount) | |
18 { | |
19 int result = KeyboardModifiers_None; | |
20 | |
21 if (keyboardState != NULL) | |
22 { | |
23 if (SDL_SCANCODE_LSHIFT < scancodeCount && | |
24 keyboardState[SDL_SCANCODE_LSHIFT]) | |
25 { | |
26 result |= KeyboardModifiers_Shift; | |
27 } | |
28 | |
29 if (SDL_SCANCODE_RSHIFT < scancodeCount && | |
30 keyboardState[SDL_SCANCODE_RSHIFT]) | |
31 { | |
32 result |= KeyboardModifiers_Shift; | |
33 } | |
34 | |
35 if (SDL_SCANCODE_LCTRL < scancodeCount && | |
36 keyboardState[SDL_SCANCODE_LCTRL]) | |
37 { | |
38 result |= KeyboardModifiers_Control; | |
39 } | |
40 | |
41 if (SDL_SCANCODE_RCTRL < scancodeCount && | |
42 keyboardState[SDL_SCANCODE_RCTRL]) | |
43 { | |
44 result |= KeyboardModifiers_Control; | |
45 } | |
46 | |
47 if (SDL_SCANCODE_LALT < scancodeCount && | |
48 keyboardState[SDL_SCANCODE_LALT]) | |
49 { | |
50 result |= KeyboardModifiers_Alt; | |
51 } | |
52 | |
53 if (SDL_SCANCODE_RALT < scancodeCount && | |
54 keyboardState[SDL_SCANCODE_RALT]) | |
55 { | |
56 result |= KeyboardModifiers_Alt; | |
57 } | |
58 } | |
59 | |
60 return static_cast<KeyboardModifiers>(result); | |
61 } | |
62 | |
63 | |
64 static void GetPointerEvent(PointerEvent& p, | |
65 const ICompositor& compositor, | |
66 SDL_Event event, | |
67 const uint8_t* keyboardState, | |
68 const int scancodeCount) | |
69 { | |
70 KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount); | |
71 | |
72 switch (event.button.button) | |
73 { | |
74 case SDL_BUTTON_LEFT: | |
75 p.SetMouseButton(OrthancStone::MouseButton_Left); | |
76 break; | |
77 | |
78 case SDL_BUTTON_RIGHT: | |
79 p.SetMouseButton(OrthancStone::MouseButton_Right); | |
80 break; | |
81 | |
82 case SDL_BUTTON_MIDDLE: | |
83 p.SetMouseButton(OrthancStone::MouseButton_Middle); | |
84 break; | |
85 | |
86 default: | |
87 p.SetMouseButton(OrthancStone::MouseButton_None); | |
88 break; | |
89 } | |
90 | |
91 p.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); | |
92 p.SetAltModifier(modifiers & KeyboardModifiers_Alt); | |
93 p.SetControlModifier(modifiers & KeyboardModifiers_Control); | |
94 p.SetShiftModifier(modifiers & KeyboardModifiers_Shift); | |
95 } | |
96 | |
97 } | |
98 | |
99 /** | |
100 * IMPORTANT: The full arguments to "main()" are needed for SDL on | |
101 * Windows. Otherwise, one gets the linking error "undefined reference | |
102 * to `SDL_main'". https://wiki.libsdl.org/FAQWindows | |
103 **/ | |
104 int main(int argc, char* argv[]) | |
105 { | |
106 try | |
107 { | |
108 OrthancStone::StoneInitialize(); | |
109 Orthanc::Logging::EnableInfoLevel(true); | |
110 //Orthanc::Logging::EnableTraceLevel(true); | |
111 | |
112 { | |
113 | |
114 #if 1 | |
115 boost::shared_ptr<OrthancStone::SdlViewport> viewport = | |
116 OrthancStone::SdlOpenGLViewport::Create("Stone of Orthanc", 800, 600); | |
117 #else | |
118 boost::shared_ptr<OrthancStone::SdlViewport> viewport = | |
119 OrthancStone::SdlCairoViewport::Create("Stone of Orthanc", 800, 600); | |
120 #endif | |
121 | |
122 OrthancStone::GenericLoadersContext context(1, 4, 1); | |
123 | |
124 context.StartOracle(); | |
125 | |
126 { | |
127 | |
128 boost::shared_ptr<SdlSimpleViewerApplication> application( | |
129 SdlSimpleViewerApplication::Create(context, viewport)); | |
130 | |
131 OrthancStone::DicomSource source; | |
132 | |
133 // Default and command-line parameters | |
134 const char* instanceId = "285dece8-e1956b38-cdc7d084-6ce3371e-536a9ffc"; | |
135 unsigned int frameIndex = 0; | |
136 | |
137 if (argc == 1) | |
138 { | |
139 LOG(ERROR) << "No instanceId supplied. The default of " << instanceId << " will be used. " | |
140 << "Please supply the Orthanc instance ID of the frame you wish to display then, optionally, " | |
141 << "the zero-based index of the frame (for multi-frame instances)"; | |
142 // TODO: frame number as second argument... | |
143 } | |
144 | |
145 if (argc >= 2) | |
146 instanceId = argv[1]; | |
147 | |
148 if (argc >= 3) | |
149 frameIndex = atoi(argv[1]); | |
150 | |
151 if (argc > 3) | |
152 { | |
153 LOG(ERROR) << "Extra arguments ignored!"; | |
154 } | |
155 | |
156 | |
157 application->LoadOrthancFrame(source, instanceId, frameIndex); | |
158 | |
159 OrthancStone::DefaultViewportInteractor interactor; | |
160 | |
161 { | |
162 int scancodeCount = 0; | |
163 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); | |
164 | |
165 bool stop = false; | |
166 while (!stop) | |
167 { | |
168 bool paint = false; | |
169 SDL_Event event; | |
170 while (SDL_PollEvent(&event)) | |
171 { | |
172 if (event.type == SDL_QUIT) | |
173 { | |
174 stop = true; | |
175 break; | |
176 } | |
177 else if (viewport->IsRefreshEvent(event)) | |
178 { | |
179 paint = true; | |
180 } | |
181 else if (event.type == SDL_WINDOWEVENT && | |
182 (event.window.event == SDL_WINDOWEVENT_RESIZED || | |
183 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)) | |
184 { | |
185 viewport->UpdateSize(event.window.data1, event.window.data2); | |
186 } | |
187 else if (event.type == SDL_WINDOWEVENT && | |
188 (event.window.event == SDL_WINDOWEVENT_SHOWN || | |
189 event.window.event == SDL_WINDOWEVENT_EXPOSED)) | |
190 { | |
191 paint = true; | |
192 } | |
193 else if (event.type == SDL_KEYDOWN && | |
194 event.key.repeat == 0 /* Ignore key bounce */) | |
195 { | |
196 switch (event.key.keysym.sym) | |
197 { | |
198 case SDLK_f: | |
199 viewport->ToggleMaximize(); | |
200 break; | |
201 | |
202 case SDLK_s: | |
203 application->FitContent(); | |
204 break; | |
205 | |
206 case SDLK_q: | |
207 stop = true; | |
208 break; | |
209 | |
210 default: | |
211 break; | |
212 } | |
213 } | |
214 else if (event.type == SDL_MOUSEBUTTONDOWN || | |
215 event.type == SDL_MOUSEMOTION || | |
216 event.type == SDL_MOUSEBUTTONUP) | |
217 { | |
218 std::auto_ptr<OrthancStone::IViewport::ILock> lock(viewport->Lock()); | |
219 if (lock->HasCompositor()) | |
220 { | |
221 OrthancStone::PointerEvent p; | |
222 OrthancStone::GetPointerEvent(p, lock->GetCompositor(), | |
223 event, keyboardState, scancodeCount); | |
224 | |
225 switch (event.type) | |
226 { | |
227 case SDL_MOUSEBUTTONDOWN: | |
228 lock->GetController().HandleMousePress(interactor, p, | |
229 lock->GetCompositor().GetCanvasWidth(), | |
230 lock->GetCompositor().GetCanvasHeight()); | |
231 lock->Invalidate(); | |
232 break; | |
233 | |
234 case SDL_MOUSEMOTION: | |
235 if (lock->GetController().HandleMouseMove(p)) | |
236 { | |
237 lock->Invalidate(); | |
238 } | |
239 break; | |
240 | |
241 case SDL_MOUSEBUTTONUP: | |
242 lock->GetController().HandleMouseRelease(p); | |
243 lock->Invalidate(); | |
244 break; | |
245 | |
246 default: | |
247 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
248 } | |
249 } | |
250 } | |
251 } | |
252 | |
253 if (paint) | |
254 { | |
255 viewport->Paint(); | |
256 } | |
257 | |
258 // Small delay to avoid using 100% of CPU | |
259 SDL_Delay(1); | |
260 } | |
261 } | |
262 | |
263 context.StopOracle(); | |
264 } | |
265 } | |
266 | |
267 OrthancStone::StoneFinalize(); | |
268 return 0; | |
269 } | |
270 catch (Orthanc::OrthancException & e) | |
271 { | |
272 auto test = e.What(); | |
273 fprintf(stdout, test); | |
274 LOG(ERROR) << "OrthancException: " << e.What(); | |
275 return -1; | |
276 } | |
277 catch (OrthancStone::StoneException & e) | |
278 { | |
279 LOG(ERROR) << "StoneException: " << e.What(); | |
280 return -1; | |
281 } | |
282 catch (std::runtime_error & e) | |
283 { | |
284 LOG(ERROR) << "Runtime error: " << e.what(); | |
285 return -1; | |
286 } | |
287 catch (...) | |
288 { | |
289 LOG(ERROR) << "Native exception"; | |
290 return -1; | |
291 } | |
292 } |