comparison Applications/Samples/Deprecated/SimpleViewer/SimpleViewerApplication.cpp @ 1347:bfd77672d825 broker

Moved Application/Samples/* to Application/Samples/Deprecated/*
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 07 Apr 2020 14:29:01 +0200
parents Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp@2d8ab34c8c91
children
comparison
equal deleted inserted replaced
1346:df8bf351c23f 1347:bfd77672d825
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 "SimpleViewerApplication.h"
23
24 #if ORTHANC_ENABLE_QT == 1
25 # include "Qt/SimpleViewerMainWindow.h"
26 #endif
27
28 #if ORTHANC_ENABLE_WASM == 1
29 # include <Platforms/Wasm/WasmViewport.h>
30 #endif
31
32 namespace SimpleViewer
33 {
34
35 void SimpleViewerApplication::Initialize(StoneApplicationContext* context,
36 Deprecated::IStatusBar& statusBar,
37 const boost::program_options::variables_map& parameters)
38 {
39 context_ = context;
40 statusBar_ = &statusBar;
41
42 {// initialize viewports and layout
43 mainLayout_ = new Deprecated::LayoutWidget("main-layout");
44 mainLayout_->SetPadding(10);
45 mainLayout_->SetBackgroundCleared(true);
46 mainLayout_->SetBackgroundColor(0, 0, 0);
47 mainLayout_->SetHorizontal();
48
49 thumbnailsLayout_ = new Deprecated::LayoutWidget("thumbnail-layout");
50 thumbnailsLayout_->SetPadding(10);
51 thumbnailsLayout_->SetBackgroundCleared(true);
52 thumbnailsLayout_->SetBackgroundColor(50, 50, 50);
53 thumbnailsLayout_->SetVertical();
54
55 mainWidget_ = new Deprecated::SliceViewerWidget(IObserver::GetBroker(), "main-viewport");
56 //mainWidget_->RegisterObserver(*this);
57
58 // hierarchy
59 mainLayout_->AddWidget(thumbnailsLayout_);
60 mainLayout_->AddWidget(mainWidget_);
61
62 // sources
63 smartLoader_.reset(new Deprecated::SmartLoader(IObserver::GetBroker(), context->GetOrthancApiClient()));
64 smartLoader_->SetImageQuality(Deprecated::SliceImageQuality_FullPam);
65
66 mainLayout_->SetTransmitMouseOver(true);
67 mainWidgetInteractor_.reset(new MainWidgetInteractor(*this));
68 mainWidget_->SetInteractor(*mainWidgetInteractor_);
69 thumbnailInteractor_.reset(new ThumbnailInteractor(*this));
70 }
71
72 statusBar.SetMessage("Use the key \"s\" to reinitialize the layout");
73 statusBar.SetMessage("Use the key \"n\" to go to next image in the main viewport");
74
75
76 if (parameters.count("studyId") < 1)
77 {
78 LOG(WARNING) << "The study ID is missing, will take the first studyId found in Orthanc";
79 context->GetOrthancApiClient().GetJsonAsync("/studies", new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>(*this, &SimpleViewerApplication::OnStudyListReceived));
80 }
81 else
82 {
83 SelectStudy(parameters["studyId"].as<std::string>());
84 }
85 }
86
87
88 void SimpleViewerApplication::DeclareStartupOptions(boost::program_options::options_description& options)
89 {
90 boost::program_options::options_description generic("Sample options");
91 generic.add_options()
92 ("studyId", boost::program_options::value<std::string>(),
93 "Orthanc ID of the study")
94 ;
95
96 options.add(generic);
97 }
98
99 void SimpleViewerApplication::OnStudyListReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
100 {
101 const Json::Value& response = message.GetJson();
102
103 if (response.isArray() &&
104 response.size() >= 1)
105 {
106 SelectStudy(response[0].asString());
107 }
108 }
109 void SimpleViewerApplication::OnStudyReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
110 {
111 const Json::Value& response = message.GetJson();
112
113 if (response.isObject() && response["Series"].isArray())
114 {
115 for (size_t i=0; i < response["Series"].size(); i++)
116 {
117 context_->GetOrthancApiClient().GetJsonAsync("/series/" + response["Series"][(int)i].asString(), new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>(*this, &SimpleViewerApplication::OnSeriesReceived));
118 }
119 }
120 }
121
122 void SimpleViewerApplication::OnSeriesReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
123 {
124 const Json::Value& response = message.GetJson();
125
126 if (response.isObject() &&
127 response["Instances"].isArray() &&
128 response["Instances"].size() > 0)
129 {
130 // keep track of all instances IDs
131 const std::string& seriesId = response["ID"].asString();
132 seriesTags_[seriesId] = response;
133 instancesIdsPerSeriesId_[seriesId] = std::vector<std::string>();
134 for (size_t i = 0; i < response["Instances"].size(); i++)
135 {
136 const std::string& instanceId = response["Instances"][static_cast<int>(i)].asString();
137 instancesIdsPerSeriesId_[seriesId].push_back(instanceId);
138 }
139
140 // load the first instance in the thumbnail
141 LoadThumbnailForSeries(seriesId, instancesIdsPerSeriesId_[seriesId][0]);
142
143 // if this is the first thumbnail loaded, load the first instance in the mainWidget
144 if (mainWidget_->GetLayerCount() == 0)
145 {
146 smartLoader_->SetFrameInWidget(*mainWidget_, 0, instancesIdsPerSeriesId_[seriesId][0], 0);
147 }
148 }
149 }
150
151 void SimpleViewerApplication::LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId)
152 {
153 LOG(INFO) << "Loading thumbnail for series " << seriesId;
154
155 Deprecated::SliceViewerWidget* thumbnailWidget =
156 new Deprecated::SliceViewerWidget(IObserver::GetBroker(), "thumbnail-series-" + seriesId);
157 thumbnails_.push_back(thumbnailWidget);
158 thumbnailsLayout_->AddWidget(thumbnailWidget);
159
160 thumbnailWidget->RegisterObserverCallback(
161 new Callable<SimpleViewerApplication, Deprecated::SliceViewerWidget::GeometryChangedMessage>
162 (*this, &SimpleViewerApplication::OnWidgetGeometryChanged));
163
164 smartLoader_->SetFrameInWidget(*thumbnailWidget, 0, instanceId, 0);
165 thumbnailWidget->SetInteractor(*thumbnailInteractor_);
166 }
167
168 void SimpleViewerApplication::SelectStudy(const std::string& studyId)
169 {
170 context_->GetOrthancApiClient().GetJsonAsync("/studies/" + studyId, new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>(*this, &SimpleViewerApplication::OnStudyReceived));
171 }
172
173 void SimpleViewerApplication::OnWidgetGeometryChanged(const Deprecated::SliceViewerWidget::GeometryChangedMessage& message)
174 {
175 // TODO: The "const_cast" could probably be replaced by "mainWidget_"
176 const_cast<Deprecated::SliceViewerWidget&>(message.GetOrigin()).FitContent();
177 }
178
179 void SimpleViewerApplication::SelectSeriesInMainViewport(const std::string& seriesId)
180 {
181 smartLoader_->SetFrameInWidget(*mainWidget_, 0, instancesIdsPerSeriesId_[seriesId][0], 0);
182 }
183
184 bool SimpleViewerApplication::Handle(const StoneSampleCommands::SelectTool& value)
185 {
186 currentTool_ = value.tool;
187 return true;
188 }
189
190 bool SimpleViewerApplication::Handle(const StoneSampleCommands::Action& value)
191 {
192 switch (value.type)
193 {
194 case ActionType_Invert:
195 // TODO
196 break;
197 case ActionType_UndoCrop:
198 // TODO
199 break;
200 case ActionType_Rotate:
201 // TODO
202 break;
203 default:
204 throw std::runtime_error("Action type not supported");
205 }
206 return true;
207 }
208
209 #if ORTHANC_ENABLE_QT==1
210 QStoneMainWindow* SimpleViewerApplication::CreateQtMainWindow()
211 {
212 return new SimpleViewerMainWindow(dynamic_cast<OrthancStone::NativeStoneApplicationContext&>(*context_), *this);
213 }
214 #endif
215
216 #if ORTHANC_ENABLE_WASM==1
217 void SimpleViewerApplication::InitializeWasm() {
218
219 AttachWidgetToWasmViewport("canvasThumbnails", thumbnailsLayout_);
220 AttachWidgetToWasmViewport("canvasMain", mainWidget_);
221 }
222 #endif
223
224
225 }