comparison OrthancStone/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp @ 1512:244ad1e4e76a

reorganization of folders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 Jul 2020 16:21:02 +0200
parents Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp@169adf9090a6
children c7a37c3a0b8e
comparison
equal deleted inserted replaced
1511:9dfeee74c1e6 1512:244ad1e4e76a
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "SdlSimpleViewerApplication.h"
23 #include "../SdlHelpers.h"
24 #include "../../Common/SampleHelpers.h"
25
26 #include "../../../Sources/Loaders/GenericLoadersContext.h"
27 #include "../../../Sources/StoneException.h"
28 #include "../../../Sources/StoneEnumerations.h"
29 #include "../../../Sources/StoneInitialization.h"
30 #include "../../../Sources/Viewport/SdlViewport.h"
31
32 #include <Compatibility.h> // For std::unique_ptr<>
33 #include <OrthancException.h>
34
35 #include <boost/program_options.hpp>
36 #include <SDL.h>
37
38 #include <string>
39
40
41 std::string orthancUrl;
42 std::string instanceId;
43 int frameIndex = 0;
44
45
46 static void ProcessOptions(int argc, char* argv[])
47 {
48 namespace po = boost::program_options;
49 po::options_description desc("Usage:");
50
51 desc.add_options()
52 ("loglevel", po::value<std::string>()->default_value("WARNING"),
53 "You can choose WARNING, INFO or TRACE for the logging level: Errors and warnings will always be displayed. (default: WARNING)")
54
55 ("orthanc", po::value<std::string>()->default_value("http://localhost:8042"),
56 "Base URL of the Orthanc instance")
57
58 ("instance", po::value<std::string>()->default_value("285dece8-e1956b38-cdc7d084-6ce3371e-536a9ffc"),
59 "Orthanc ID of the instance to display")
60
61 ("frame_index", po::value<int>()->default_value(0),
62 "The zero-based index of the frame (for multi-frame instances)")
63 ;
64
65 po::variables_map vm;
66 try
67 {
68 po::store(po::parse_command_line(argc, argv, desc), vm);
69 po::notify(vm);
70 }
71 catch (std::exception& e)
72 {
73 std::cerr << "Please check your command line options! (\"" << e.what() << "\")" << std::endl;
74 }
75
76 if (vm.count("loglevel") > 0)
77 {
78 std::string logLevel = vm["loglevel"].as<std::string>();
79 OrthancStoneHelpers::SetLogLevel(logLevel);
80 }
81
82 if (vm.count("orthanc") > 0)
83 {
84 // maybe check URL validity here
85 orthancUrl = vm["orthanc"].as<std::string>();
86 }
87
88 if (vm.count("instance") > 0)
89 {
90 instanceId = vm["instance"].as<std::string>();
91 }
92
93 if (vm.count("frame_index") > 0)
94 {
95 frameIndex = vm["frame_index"].as<int>();
96 }
97
98 }
99
100 /**
101 * IMPORTANT: The full arguments to "main()" are needed for SDL on
102 * Windows. Otherwise, one gets the linking error "undefined reference
103 * to `SDL_main'". https://wiki.libsdl.org/FAQWindows
104 **/
105 int main(int argc, char* argv[])
106 {
107 try
108 {
109 OrthancStone::StoneInitialize();
110
111 ProcessOptions(argc, argv);
112
113 //Orthanc::Logging::EnableInfoLevel(true);
114 //Orthanc::Logging::EnableTraceLevel(true);
115
116 {
117
118 #if 1
119 boost::shared_ptr<OrthancStone::SdlViewport> viewport =
120 OrthancStone::SdlOpenGLViewport::Create("Stone of Orthanc", 800, 600);
121 #else
122 boost::shared_ptr<OrthancStone::SdlViewport> viewport =
123 OrthancStone::SdlCairoViewport::Create("Stone of Orthanc", 800, 600);
124 #endif
125
126 OrthancStone::GenericLoadersContext context(1, 4, 1);
127
128 Orthanc::WebServiceParameters orthancWebService;
129 orthancWebService.SetUrl(orthancUrl);
130 context.SetOrthancParameters(orthancWebService);
131
132 context.StartOracle();
133
134 {
135
136 boost::shared_ptr<SdlSimpleViewerApplication> application(
137 SdlSimpleViewerApplication::Create(context, viewport));
138
139 OrthancStone::DicomSource source;
140
141 application->LoadOrthancFrame(source, instanceId, frameIndex);
142
143 OrthancStone::DefaultViewportInteractor interactor;
144
145 {
146 int scancodeCount = 0;
147 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
148
149 bool stop = false;
150 while (!stop)
151 {
152 bool paint = false;
153 SDL_Event event;
154 while (SDL_PollEvent(&event))
155 {
156 if (event.type == SDL_QUIT)
157 {
158 stop = true;
159 break;
160 }
161 else if (viewport->IsRefreshEvent(event))
162 {
163 paint = true;
164 }
165 else if (event.type == SDL_WINDOWEVENT &&
166 (event.window.event == SDL_WINDOWEVENT_RESIZED ||
167 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED))
168 {
169 viewport->UpdateSize(event.window.data1, event.window.data2);
170 }
171 else if (event.type == SDL_WINDOWEVENT &&
172 (event.window.event == SDL_WINDOWEVENT_SHOWN ||
173 event.window.event == SDL_WINDOWEVENT_EXPOSED))
174 {
175 paint = true;
176 }
177 else if (event.type == SDL_KEYDOWN &&
178 event.key.repeat == 0 /* Ignore key bounce */)
179 {
180 switch (event.key.keysym.sym)
181 {
182 case SDLK_f:
183 viewport->ToggleMaximize();
184 break;
185
186 case SDLK_s:
187 application->FitContent();
188 break;
189
190 case SDLK_q:
191 stop = true;
192 break;
193
194 default:
195 break;
196 }
197 }
198 else if (event.type == SDL_MOUSEBUTTONDOWN ||
199 event.type == SDL_MOUSEMOTION ||
200 event.type == SDL_MOUSEBUTTONUP)
201 {
202 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport->Lock());
203 if (lock->HasCompositor())
204 {
205 OrthancStone::PointerEvent p;
206 OrthancStoneHelpers::GetPointerEvent(p, lock->GetCompositor(),
207 event, keyboardState, scancodeCount);
208
209 switch (event.type)
210 {
211 case SDL_MOUSEBUTTONDOWN:
212 lock->GetController().HandleMousePress(interactor, p,
213 lock->GetCompositor().GetCanvasWidth(),
214 lock->GetCompositor().GetCanvasHeight());
215 lock->Invalidate();
216 break;
217
218 case SDL_MOUSEMOTION:
219 if (lock->GetController().HandleMouseMove(p))
220 {
221 lock->Invalidate();
222 }
223 break;
224
225 case SDL_MOUSEBUTTONUP:
226 lock->GetController().HandleMouseRelease(p);
227 lock->Invalidate();
228 break;
229
230 default:
231 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
232 }
233 }
234 }
235 }
236
237 if (paint)
238 {
239 viewport->Paint();
240 }
241
242 // Small delay to avoid using 100% of CPU
243 SDL_Delay(1);
244 }
245 }
246 context.StopOracle();
247 }
248 }
249
250 OrthancStone::StoneFinalize();
251 return 0;
252 }
253 catch (Orthanc::OrthancException& e)
254 {
255 LOG(ERROR) << "OrthancException: " << e.What();
256 return -1;
257 }
258 catch (OrthancStone::StoneException& e)
259 {
260 LOG(ERROR) << "StoneException: " << e.What();
261 return -1;
262 }
263 catch (std::runtime_error& e)
264 {
265 LOG(ERROR) << "Runtime error: " << e.what();
266 return -1;
267 }
268 catch (...)
269 {
270 LOG(ERROR) << "Native exception";
271 return -1;
272 }
273 }