1368
|
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 }
|