Mercurial > hg > orthanc-stone
comparison Samples/WebAssembly/dev.h @ 826:2de01660debe
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 29 May 2019 16:48:56 +0200 |
parents | |
children | 5cfb479fdbde 77c96ba899f9 |
comparison
equal
deleted
inserted
replaced
825:9a6c7a5dcb76 | 826:2de01660debe |
---|---|
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-2019 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 #pragma once | |
23 | |
24 #include "../../Framework/OpenGL/WebAssemblyOpenGLContext.h" | |
25 #include "../../Framework/Scene2D/OpenGLCompositor.h" | |
26 #include "../../Framework/Scene2D/PanSceneTracker.h" | |
27 #include "../../Framework/Scene2D/RotateSceneTracker.h" | |
28 #include "../../Framework/Scene2D/ZoomSceneTracker.h" | |
29 #include "../../Framework/Scene2DViewport/ViewportController.h" | |
30 | |
31 #include <Core/OrthancException.h> | |
32 | |
33 #include <emscripten/html5.h> | |
34 | |
35 static const unsigned int FONT_SIZE = 32; | |
36 | |
37 namespace OrthancStone | |
38 { | |
39 class WebAssemblyViewport : public boost::noncopyable | |
40 { | |
41 private: | |
42 // the construction order is important because compositor_ | |
43 // will hold a reference to the scene that belong to the | |
44 // controller_ object | |
45 OpenGL::WebAssemblyOpenGLContext context_; | |
46 boost::shared_ptr<ViewportController> controller_; | |
47 OpenGLCompositor compositor_; | |
48 | |
49 void SetupEvents(const std::string& canvas); | |
50 | |
51 public: | |
52 WebAssemblyViewport(MessageBroker& broker, | |
53 const std::string& canvas) : | |
54 context_(canvas), | |
55 controller_(new ViewportController(broker)), | |
56 compositor_(context_, *controller_->GetScene()) | |
57 { | |
58 compositor_.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, | |
59 FONT_SIZE, Orthanc::Encoding_Latin1); | |
60 SetupEvents(canvas); | |
61 } | |
62 | |
63 Scene2D& GetScene() | |
64 { | |
65 return *controller_->GetScene(); | |
66 } | |
67 | |
68 const boost::shared_ptr<ViewportController>& GetController() | |
69 { | |
70 return controller_; | |
71 } | |
72 | |
73 void UpdateSize() | |
74 { | |
75 context_.UpdateSize(); | |
76 compositor_.UpdateSize(); | |
77 Refresh(); | |
78 } | |
79 | |
80 void Refresh() | |
81 { | |
82 compositor_.Refresh(); | |
83 } | |
84 | |
85 void FitContent() | |
86 { | |
87 GetScene().FitContent(context_.GetCanvasWidth(), context_.GetCanvasHeight()); | |
88 } | |
89 | |
90 const std::string& GetCanvasIdentifier() const | |
91 { | |
92 return context_.GetCanvasIdentifier(); | |
93 } | |
94 | |
95 ScenePoint2D GetPixelCenterCoordinates(int x, int y) const | |
96 { | |
97 return compositor_.GetPixelCenterCoordinates(x, y); | |
98 } | |
99 | |
100 unsigned int GetCanvasWidth() const | |
101 { | |
102 return context_.GetCanvasWidth(); | |
103 } | |
104 | |
105 unsigned int GetCanvasHeight() const | |
106 { | |
107 return context_.GetCanvasHeight(); | |
108 } | |
109 }; | |
110 | |
111 class ActiveTracker : public boost::noncopyable | |
112 { | |
113 private: | |
114 boost::shared_ptr<IFlexiblePointerTracker> tracker_; | |
115 std::string canvasIdentifier_; | |
116 bool insideCanvas_; | |
117 | |
118 public: | |
119 ActiveTracker(const boost::shared_ptr<IFlexiblePointerTracker>& tracker, | |
120 const WebAssemblyViewport& viewport) : | |
121 tracker_(tracker), | |
122 canvasIdentifier_(viewport.GetCanvasIdentifier()), | |
123 insideCanvas_(true) | |
124 { | |
125 if (tracker_.get() == NULL) | |
126 { | |
127 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
128 } | |
129 } | |
130 | |
131 bool IsAlive() const | |
132 { | |
133 return tracker_->IsAlive(); | |
134 } | |
135 | |
136 void PointerMove(const PointerEvent& event) | |
137 { | |
138 tracker_->PointerMove(event); | |
139 } | |
140 | |
141 void PointerUp(const PointerEvent& event) | |
142 { | |
143 tracker_->PointerUp(event); | |
144 } | |
145 }; | |
146 } | |
147 | |
148 static OrthancStone::PointerEvent* ConvertMouseEvent( | |
149 const EmscriptenMouseEvent& source, | |
150 OrthancStone::WebAssemblyViewport& viewport) | |
151 { | |
152 std::auto_ptr<OrthancStone::PointerEvent> target( | |
153 new OrthancStone::PointerEvent); | |
154 | |
155 target->AddPosition(viewport.GetPixelCenterCoordinates( | |
156 source.targetX, source.targetY)); | |
157 target->SetAltModifier(source.altKey); | |
158 target->SetControlModifier(source.ctrlKey); | |
159 target->SetShiftModifier(source.shiftKey); | |
160 | |
161 return target.release(); | |
162 } | |
163 | |
164 std::auto_ptr<OrthancStone::ActiveTracker> tracker_; | |
165 | |
166 EM_BOOL OnMouseEvent(int eventType, | |
167 const EmscriptenMouseEvent *mouseEvent, | |
168 void *userData) | |
169 { | |
170 if (mouseEvent != NULL && | |
171 userData != NULL) | |
172 { | |
173 OrthancStone::WebAssemblyViewport& viewport = | |
174 *reinterpret_cast<OrthancStone::WebAssemblyViewport*>(userData); | |
175 | |
176 switch (eventType) | |
177 { | |
178 case EMSCRIPTEN_EVENT_CLICK: | |
179 { | |
180 static unsigned int count = 0; | |
181 char buf[64]; | |
182 sprintf(buf, "click %d", count++); | |
183 | |
184 std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer); | |
185 layer->SetText(buf); | |
186 viewport.GetScene().SetLayer(100, layer.release()); | |
187 viewport.Refresh(); | |
188 break; | |
189 } | |
190 | |
191 case EMSCRIPTEN_EVENT_MOUSEDOWN: | |
192 { | |
193 boost::shared_ptr<OrthancStone::IFlexiblePointerTracker> t; | |
194 | |
195 { | |
196 std::auto_ptr<OrthancStone::PointerEvent> event( | |
197 ConvertMouseEvent(*mouseEvent, viewport)); | |
198 | |
199 switch (mouseEvent->button) | |
200 { | |
201 case 0: // Left button | |
202 emscripten_console_log("Creating RotateSceneTracker"); | |
203 t.reset(new OrthancStone::RotateSceneTracker( | |
204 viewport.GetController(), *event)); | |
205 break; | |
206 | |
207 case 1: // Middle button | |
208 emscripten_console_log("Creating PanSceneTracker"); | |
209 LOG(INFO) << "Creating PanSceneTracker" ; | |
210 t.reset(new OrthancStone::PanSceneTracker( | |
211 viewport.GetController(), *event)); | |
212 break; | |
213 | |
214 case 2: // Right button | |
215 emscripten_console_log("Creating ZoomSceneTracker"); | |
216 t.reset(new OrthancStone::ZoomSceneTracker( | |
217 viewport.GetController(), *event, viewport.GetCanvasWidth())); | |
218 break; | |
219 | |
220 default: | |
221 break; | |
222 } | |
223 } | |
224 | |
225 if (t.get() != NULL) | |
226 { | |
227 tracker_.reset( | |
228 new OrthancStone::ActiveTracker(t, viewport)); | |
229 viewport.Refresh(); | |
230 } | |
231 | |
232 break; | |
233 } | |
234 | |
235 case EMSCRIPTEN_EVENT_MOUSEMOVE: | |
236 if (tracker_.get() != NULL) | |
237 { | |
238 std::auto_ptr<OrthancStone::PointerEvent> event( | |
239 ConvertMouseEvent(*mouseEvent, viewport)); | |
240 tracker_->PointerMove(*event); | |
241 viewport.Refresh(); | |
242 } | |
243 break; | |
244 | |
245 case EMSCRIPTEN_EVENT_MOUSEUP: | |
246 if (tracker_.get() != NULL) | |
247 { | |
248 std::auto_ptr<OrthancStone::PointerEvent> event( | |
249 ConvertMouseEvent(*mouseEvent, viewport)); | |
250 tracker_->PointerUp(*event); | |
251 viewport.Refresh(); | |
252 if (!tracker_->IsAlive()) | |
253 tracker_.reset(); | |
254 } | |
255 break; | |
256 | |
257 default: | |
258 break; | |
259 } | |
260 } | |
261 | |
262 return true; | |
263 } | |
264 | |
265 | |
266 void OrthancStone::WebAssemblyViewport::SetupEvents(const std::string& canvas) | |
267 { | |
268 emscripten_set_mousedown_callback(canvas.c_str(), this, false, OnMouseEvent); | |
269 emscripten_set_mousemove_callback(canvas.c_str(), this, false, OnMouseEvent); | |
270 emscripten_set_mouseup_callback(canvas.c_str(), this, false, OnMouseEvent); | |
271 } |