# HG changeset patch # User Sebastien Jodogne # Date 1591939171 -7200 # Node ID 182bf3106ee205542b67add8615c1a8ebaf433fa # Parent b17d0359972655dee981721c3058779dddbeeaf0 dos2unix diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Applications/Generic/Scene2DInteractor.h --- a/Deprecated/Applications/Generic/Scene2DInteractor.h Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Applications/Generic/Scene2DInteractor.h Fri Jun 12 07:19:31 2020 +0200 @@ -1,52 +1,52 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ -#pragma once - -#include "../../Framework/Scene2D/PointerEvent.h" -#include "../../Framework/Scene2DViewport/ViewportController.h" -//#include "../../Framework/Scene2D/Internals/CompositorHelper.h" -#include "GuiAdapter.h" - - -namespace OrthancStone -{ - - class Scene2DInteractor - { - protected: - boost::shared_ptr viewportController_; -// boost::shared_ptr compositor_; - - public: - Scene2DInteractor(boost::shared_ptr viewportController) : - viewportController_(viewportController) - {} - -// void SetCompositor(boost::shared_ptr compositor) -// { -// compositor_ = compositor; -// } - - virtual bool OnMouseEvent(const GuiAdapterMouseEvent& guiEvent, const PointerEvent& pointerEvent) = 0; // returns true if it has handled the event - virtual bool OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent) = 0; // returns true if it has handled the event - virtual bool OnWheelEvent(const GuiAdapterWheelEvent& guiEvent) = 0; // returns true if it has handled the event - - }; -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ +#pragma once + +#include "../../Framework/Scene2D/PointerEvent.h" +#include "../../Framework/Scene2DViewport/ViewportController.h" +//#include "../../Framework/Scene2D/Internals/CompositorHelper.h" +#include "GuiAdapter.h" + + +namespace OrthancStone +{ + + class Scene2DInteractor + { + protected: + boost::shared_ptr viewportController_; +// boost::shared_ptr compositor_; + + public: + Scene2DInteractor(boost::shared_ptr viewportController) : + viewportController_(viewportController) + {} + +// void SetCompositor(boost::shared_ptr compositor) +// { +// compositor_ = compositor; +// } + + virtual bool OnMouseEvent(const GuiAdapterMouseEvent& guiEvent, const PointerEvent& pointerEvent) = 0; // returns true if it has handled the event + virtual bool OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent) = 0; // returns true if it has handled the event + virtual bool OnWheelEvent(const GuiAdapterWheelEvent& guiEvent) = 0; // returns true if it has handled the event + + }; +} diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.cpp --- a/Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -1,275 +1,275 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - -#include "BasicScene.h" - -// From Stone -#include "Framework/Scene2D/Scene2D.h" -#include "Framework/Scene2D/ColorTextureSceneLayer.h" -#include "Framework/Scene2D/PolylineSceneLayer.h" -#include "Framework/Scene2D/TextSceneLayer.h" - -#include "Framework/Scene2D/PanSceneTracker.h" -#include "Framework/Scene2D/ZoomSceneTracker.h" -#include "Framework/Scene2D/RotateSceneTracker.h" - -#include "Framework/Scene2D/CairoCompositor.h" - -// From Orthanc framework -#include -#include -#include - -using namespace OrthancStone; - -const unsigned int BASIC_SCENE_FONT_SIZE = 32; -const int BASIC_SCENE_LAYER_POSITION = 150; - -void PrepareScene(Scene2D& scene) -{ - //Scene2D& scene(*controller->GetScene()); - // Texture of 2x2 size - { - Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); - - uint8_t *p = reinterpret_cast(i.GetRow(0)); - p[0] = 255; - p[1] = 0; - p[2] = 0; - - p[3] = 0; - p[4] = 255; - p[5] = 0; - - p = reinterpret_cast(i.GetRow(1)); - p[0] = 0; - p[1] = 0; - p[2] = 255; - - p[3] = 255; - p[4] = 0; - p[5] = 0; - - scene.SetLayer(12, new ColorTextureSceneLayer(i)); - - std::unique_ptr l(new ColorTextureSceneLayer(i)); - l->SetOrigin(-3, 2); - l->SetPixelSpacing(1.5, 1); - l->SetAngle(20.0 / 180.0 * 3.14); - scene.SetLayer(14, l.release()); - } - - // Texture of 1x1 size - { - Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false); - - uint8_t *p = reinterpret_cast(i.GetRow(0)); - p[0] = 255; - p[1] = 0; - p[2] = 0; - - std::unique_ptr l(new ColorTextureSceneLayer(i)); - l->SetOrigin(-2, 1); - l->SetAngle(20.0 / 180.0 * 3.14); - scene.SetLayer(13, l.release()); - } - - // Some lines - { - std::unique_ptr layer(new PolylineSceneLayer); - - layer->SetThickness(1); - - PolylineSceneLayer::Chain chain; - chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5)); - chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5)); - chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5)); - chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5)); - layer->AddChain(chain, true, 255, 0, 0); - - chain.clear(); - chain.push_back(ScenePoint2D(-5, -5)); - chain.push_back(ScenePoint2D(5, -5)); - chain.push_back(ScenePoint2D(5, 5)); - chain.push_back(ScenePoint2D(-5, 5)); - layer->AddChain(chain, true, 0, 255, 0); - - double dy = 1.01; - chain.clear(); - chain.push_back(ScenePoint2D(-4, -4)); - chain.push_back(ScenePoint2D(4, -4 + dy)); - chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy)); - chain.push_back(ScenePoint2D(4, 2)); - layer->AddChain(chain, false, 0, 0, 255); - - // layer->SetColor(0,255, 255); - scene.SetLayer(50, layer.release()); - } - - // Some text - { - std::unique_ptr layer(new TextSceneLayer); - layer->SetText("Hello"); - scene.SetLayer(100, layer.release()); - } -} - -#if ORTHANC_SANDBOXED == 0 -void TakeScreenshot(const std::string& target, - const OrthancStone::Scene2D& scene, - unsigned int canvasWidth, - unsigned int canvasHeight) -{ - using namespace OrthancStone; - // Take a screenshot, then save it as PNG file - CairoCompositor compositor(scene, canvasWidth, canvasHeight); - compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1); - compositor.Refresh(); - - Orthanc::ImageAccessor canvas; - compositor.GetCanvas().GetReadOnlyAccessor(canvas); - - Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false); - Orthanc::ImageProcessing::Convert(png, canvas); - - Orthanc::PngWriter writer; - writer.WriteToFile(target, png); -} -#endif - -void ShowCursorInfo(Scene2D& scene, const PointerEvent& pointerEvent) -{ - ScenePoint2D p = pointerEvent.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); - - char buf[64]; - sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); - - if (scene.HasLayer(BASIC_SCENE_LAYER_POSITION)) - { - TextSceneLayer& layer = - dynamic_cast(scene.GetLayer(BASIC_SCENE_LAYER_POSITION)); - layer.SetText(buf); - layer.SetPosition(p.GetX(), p.GetY()); - } - else - { - std::unique_ptr - layer(new TextSceneLayer); - layer->SetColor(0, 255, 0); - layer->SetText(buf); - layer->SetBorder(20); - layer->SetAnchor(BitmapAnchor_BottomCenter); - layer->SetPosition(p.GetX(), p.GetY()); - scene.SetLayer(BASIC_SCENE_LAYER_POSITION, layer.release()); - } -} - - - -bool BasicScene2DInteractor::OnMouseEvent(const GuiAdapterMouseEvent& event, const PointerEvent& pointerEvent) -{ - if (currentTracker_.get() != NULL) - { - switch (event.type) - { - case GUIADAPTER_EVENT_MOUSEUP: - { - currentTracker_->PointerUp(pointerEvent); - if (!currentTracker_->IsAlive()) - { - currentTracker_.reset(); - } - };break; - case GUIADAPTER_EVENT_MOUSEMOVE: - { - currentTracker_->PointerMove(pointerEvent); - };break; - default: - return false; - } - return true; - } - else if (event.type == GUIADAPTER_EVENT_MOUSEDOWN) - { - if (event.button == GUIADAPTER_MOUSEBUTTON_LEFT) - { - currentTracker_.reset(new RotateSceneTracker(viewportController_, pointerEvent)); - } - else if (event.button == GUIADAPTER_MOUSEBUTTON_MIDDLE) - { - currentTracker_.reset(new PanSceneTracker(viewportController_, pointerEvent)); - } - else if (event.button == GUIADAPTER_MOUSEBUTTON_RIGHT) - { - currentTracker_.reset(new ZoomSceneTracker(viewportController_, pointerEvent, viewportController_->GetViewport().GetCanvasHeight())); - } - } - else if (event.type == GUIADAPTER_EVENT_MOUSEMOVE) - { - if (showCursorInfo_) - { - Scene2D& scene(viewportController_->GetScene()); - ShowCursorInfo(scene, pointerEvent); - } - return true; - } - return false; -} - -bool BasicScene2DInteractor::OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent) -{ - if (guiEvent.type == GUIADAPTER_EVENT_KEYDOWN) - { - switch (guiEvent.sym[0]) - { - case 's': - { - //viewportController_->FitContent(viewportController_->GetViewport().GetCanvasWidth(), viewportController_->GetViewport().GetCanvasHeight()); - viewportController_->FitContent(); - return true; - }; -#if ORTHANC_SANDBOXED == 0 - case 'c': - { - Scene2D& scene(viewportController_->GetScene()); - TakeScreenshot("screenshot.png", scene, viewportController_->GetViewport().GetCanvasWidth(), viewportController_->GetViewport().GetCanvasHeight()); - return true; - } -#endif - case 'd': - { - showCursorInfo_ = !showCursorInfo_; - if (!showCursorInfo_) - { - Scene2D& scene(viewportController_->GetScene()); - scene.DeleteLayer(BASIC_SCENE_LAYER_POSITION); - } - - return true; - } - } - } - return false; -} - -bool BasicScene2DInteractor::OnWheelEvent(const GuiAdapterWheelEvent& guiEvent) -{ - return false; -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + +#include "BasicScene.h" + +// From Stone +#include "Framework/Scene2D/Scene2D.h" +#include "Framework/Scene2D/ColorTextureSceneLayer.h" +#include "Framework/Scene2D/PolylineSceneLayer.h" +#include "Framework/Scene2D/TextSceneLayer.h" + +#include "Framework/Scene2D/PanSceneTracker.h" +#include "Framework/Scene2D/ZoomSceneTracker.h" +#include "Framework/Scene2D/RotateSceneTracker.h" + +#include "Framework/Scene2D/CairoCompositor.h" + +// From Orthanc framework +#include +#include +#include + +using namespace OrthancStone; + +const unsigned int BASIC_SCENE_FONT_SIZE = 32; +const int BASIC_SCENE_LAYER_POSITION = 150; + +void PrepareScene(Scene2D& scene) +{ + //Scene2D& scene(*controller->GetScene()); + // Texture of 2x2 size + { + Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); + + uint8_t *p = reinterpret_cast(i.GetRow(0)); + p[0] = 255; + p[1] = 0; + p[2] = 0; + + p[3] = 0; + p[4] = 255; + p[5] = 0; + + p = reinterpret_cast(i.GetRow(1)); + p[0] = 0; + p[1] = 0; + p[2] = 255; + + p[3] = 255; + p[4] = 0; + p[5] = 0; + + scene.SetLayer(12, new ColorTextureSceneLayer(i)); + + std::unique_ptr l(new ColorTextureSceneLayer(i)); + l->SetOrigin(-3, 2); + l->SetPixelSpacing(1.5, 1); + l->SetAngle(20.0 / 180.0 * 3.14); + scene.SetLayer(14, l.release()); + } + + // Texture of 1x1 size + { + Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false); + + uint8_t *p = reinterpret_cast(i.GetRow(0)); + p[0] = 255; + p[1] = 0; + p[2] = 0; + + std::unique_ptr l(new ColorTextureSceneLayer(i)); + l->SetOrigin(-2, 1); + l->SetAngle(20.0 / 180.0 * 3.14); + scene.SetLayer(13, l.release()); + } + + // Some lines + { + std::unique_ptr layer(new PolylineSceneLayer); + + layer->SetThickness(1); + + PolylineSceneLayer::Chain chain; + chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5)); + chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5)); + chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5)); + chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5)); + layer->AddChain(chain, true, 255, 0, 0); + + chain.clear(); + chain.push_back(ScenePoint2D(-5, -5)); + chain.push_back(ScenePoint2D(5, -5)); + chain.push_back(ScenePoint2D(5, 5)); + chain.push_back(ScenePoint2D(-5, 5)); + layer->AddChain(chain, true, 0, 255, 0); + + double dy = 1.01; + chain.clear(); + chain.push_back(ScenePoint2D(-4, -4)); + chain.push_back(ScenePoint2D(4, -4 + dy)); + chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy)); + chain.push_back(ScenePoint2D(4, 2)); + layer->AddChain(chain, false, 0, 0, 255); + + // layer->SetColor(0,255, 255); + scene.SetLayer(50, layer.release()); + } + + // Some text + { + std::unique_ptr layer(new TextSceneLayer); + layer->SetText("Hello"); + scene.SetLayer(100, layer.release()); + } +} + +#if ORTHANC_SANDBOXED == 0 +void TakeScreenshot(const std::string& target, + const OrthancStone::Scene2D& scene, + unsigned int canvasWidth, + unsigned int canvasHeight) +{ + using namespace OrthancStone; + // Take a screenshot, then save it as PNG file + CairoCompositor compositor(scene, canvasWidth, canvasHeight); + compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1); + compositor.Refresh(); + + Orthanc::ImageAccessor canvas; + compositor.GetCanvas().GetReadOnlyAccessor(canvas); + + Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false); + Orthanc::ImageProcessing::Convert(png, canvas); + + Orthanc::PngWriter writer; + writer.WriteToFile(target, png); +} +#endif + +void ShowCursorInfo(Scene2D& scene, const PointerEvent& pointerEvent) +{ + ScenePoint2D p = pointerEvent.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); + + char buf[64]; + sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); + + if (scene.HasLayer(BASIC_SCENE_LAYER_POSITION)) + { + TextSceneLayer& layer = + dynamic_cast(scene.GetLayer(BASIC_SCENE_LAYER_POSITION)); + layer.SetText(buf); + layer.SetPosition(p.GetX(), p.GetY()); + } + else + { + std::unique_ptr + layer(new TextSceneLayer); + layer->SetColor(0, 255, 0); + layer->SetText(buf); + layer->SetBorder(20); + layer->SetAnchor(BitmapAnchor_BottomCenter); + layer->SetPosition(p.GetX(), p.GetY()); + scene.SetLayer(BASIC_SCENE_LAYER_POSITION, layer.release()); + } +} + + + +bool BasicScene2DInteractor::OnMouseEvent(const GuiAdapterMouseEvent& event, const PointerEvent& pointerEvent) +{ + if (currentTracker_.get() != NULL) + { + switch (event.type) + { + case GUIADAPTER_EVENT_MOUSEUP: + { + currentTracker_->PointerUp(pointerEvent); + if (!currentTracker_->IsAlive()) + { + currentTracker_.reset(); + } + };break; + case GUIADAPTER_EVENT_MOUSEMOVE: + { + currentTracker_->PointerMove(pointerEvent); + };break; + default: + return false; + } + return true; + } + else if (event.type == GUIADAPTER_EVENT_MOUSEDOWN) + { + if (event.button == GUIADAPTER_MOUSEBUTTON_LEFT) + { + currentTracker_.reset(new RotateSceneTracker(viewportController_, pointerEvent)); + } + else if (event.button == GUIADAPTER_MOUSEBUTTON_MIDDLE) + { + currentTracker_.reset(new PanSceneTracker(viewportController_, pointerEvent)); + } + else if (event.button == GUIADAPTER_MOUSEBUTTON_RIGHT) + { + currentTracker_.reset(new ZoomSceneTracker(viewportController_, pointerEvent, viewportController_->GetViewport().GetCanvasHeight())); + } + } + else if (event.type == GUIADAPTER_EVENT_MOUSEMOVE) + { + if (showCursorInfo_) + { + Scene2D& scene(viewportController_->GetScene()); + ShowCursorInfo(scene, pointerEvent); + } + return true; + } + return false; +} + +bool BasicScene2DInteractor::OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent) +{ + if (guiEvent.type == GUIADAPTER_EVENT_KEYDOWN) + { + switch (guiEvent.sym[0]) + { + case 's': + { + //viewportController_->FitContent(viewportController_->GetViewport().GetCanvasWidth(), viewportController_->GetViewport().GetCanvasHeight()); + viewportController_->FitContent(); + return true; + }; +#if ORTHANC_SANDBOXED == 0 + case 'c': + { + Scene2D& scene(viewportController_->GetScene()); + TakeScreenshot("screenshot.png", scene, viewportController_->GetViewport().GetCanvasWidth(), viewportController_->GetViewport().GetCanvasHeight()); + return true; + } +#endif + case 'd': + { + showCursorInfo_ = !showCursorInfo_; + if (!showCursorInfo_) + { + Scene2D& scene(viewportController_->GetScene()); + scene.DeleteLayer(BASIC_SCENE_LAYER_POSITION); + } + + return true; + } + } + } + return false; +} + +bool BasicScene2DInteractor::OnWheelEvent(const GuiAdapterWheelEvent& guiEvent) +{ + return false; +} diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.h --- a/Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.h Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.h Fri Jun 12 07:19:31 2020 +0200 @@ -1,55 +1,55 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - -#pragma once - -#include -#include "Framework/Scene2DViewport/ViewportController.h" -#include "Framework/Scene2D/Scene2D.h" - -extern const unsigned int BASIC_SCENE_FONT_SIZE; -extern const int BASIC_SCENE_LAYER_POSITION; - -extern void PrepareScene(OrthancStone::Scene2D& scene); -extern void TakeScreenshot(const std::string& target, - const OrthancStone::Scene2D& scene, - unsigned int canvasWidth, - unsigned int canvasHeight); - - -#include "Applications/Generic/Scene2DInteractor.h" -#include "Framework/Scene2DViewport/IFlexiblePointerTracker.h" - - -class BasicScene2DInteractor : public OrthancStone::Scene2DInteractor -{ - boost::shared_ptr currentTracker_; - bool showCursorInfo_; -public: - BasicScene2DInteractor(boost::shared_ptr viewportController) : - Scene2DInteractor(viewportController), - showCursorInfo_(false) - {} - - virtual bool OnMouseEvent(const OrthancStone::GuiAdapterMouseEvent& event, const OrthancStone::PointerEvent& pointerEvent) override; - virtual bool OnKeyboardEvent(const OrthancStone::GuiAdapterKeyboardEvent& guiEvent) override; - virtual bool OnWheelEvent(const OrthancStone::GuiAdapterWheelEvent& guiEvent) override; -}; - +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + +#pragma once + +#include +#include "Framework/Scene2DViewport/ViewportController.h" +#include "Framework/Scene2D/Scene2D.h" + +extern const unsigned int BASIC_SCENE_FONT_SIZE; +extern const int BASIC_SCENE_LAYER_POSITION; + +extern void PrepareScene(OrthancStone::Scene2D& scene); +extern void TakeScreenshot(const std::string& target, + const OrthancStone::Scene2D& scene, + unsigned int canvasWidth, + unsigned int canvasHeight); + + +#include "Applications/Generic/Scene2DInteractor.h" +#include "Framework/Scene2DViewport/IFlexiblePointerTracker.h" + + +class BasicScene2DInteractor : public OrthancStone::Scene2DInteractor +{ + boost::shared_ptr currentTracker_; + bool showCursorInfo_; +public: + BasicScene2DInteractor(boost::shared_ptr viewportController) : + Scene2DInteractor(viewportController), + showCursorInfo_(false) + {} + + virtual bool OnMouseEvent(const OrthancStone::GuiAdapterMouseEvent& event, const OrthancStone::PointerEvent& pointerEvent) override; + virtual bool OnKeyboardEvent(const OrthancStone::GuiAdapterKeyboardEvent& guiEvent) override; + virtual bool OnWheelEvent(const OrthancStone::GuiAdapterWheelEvent& guiEvent) override; +}; + diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/MultiPlatform/BasicScene/mainQt.cpp --- a/Deprecated/Samples/MultiPlatform/BasicScene/mainQt.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/MultiPlatform/BasicScene/mainQt.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -1,103 +1,103 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - -#define GLEW_STATIC 1 -// From Stone -#include "../../Framework/OpenGL/OpenGLIncludes.h" -#include "../../Applications/Sdl/SdlWindow.h" -#include "../../Framework/Scene2D/CairoCompositor.h" -#include "../../Framework/Scene2D/ColorTextureSceneLayer.h" -#include "../../Framework/Scene2D/OpenGLCompositor.h" -#include "../../Framework/Scene2D/PanSceneTracker.h" -#include "../../Framework/Scene2D/RotateSceneTracker.h" -#include "../../Framework/Scene2D/Scene2D.h" -#include "../../Framework/Scene2D/ZoomSceneTracker.h" -#include "../../Framework/Scene2DViewport/ViewportController.h" -#include "../../Framework/Scene2DViewport/UndoStack.h" - -#include "../../Framework/StoneInitialization.h" -#include "../../Framework/Messages/MessageBroker.h" - -// From Orthanc framework -#include -#include -#include -#include -#include - -#include -#include -#include "EmbeddedResources.h" - -#include -#include -#include - -#include "BasicScene.h" - - -using namespace OrthancStone; - - - -static void GLAPIENTRY OpenGLMessageCallback(GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam ) -{ - if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) - { - fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", - ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), - type, severity, message ); - } -} - -extern void InitGL(); - -#include -#include "BasicSceneWindow.h" - -int main(int argc, char* argv[]) -{ - QApplication a(argc, argv); - - OrthancStone::Samples::BasicSceneWindow window; - window.show(); - window.GetOpenGlWidget().Init(); - - MessageBroker broker; - boost::shared_ptr undoStack(new UndoStack); - boost::shared_ptr controller = boost::make_shared(undoStack, boost::ref(broker), window.GetOpenGlWidget()); - PrepareScene(controller->GetScene()); - - window.GetOpenGlWidget().GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, - BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1); - - boost::shared_ptr interactor(new BasicScene2DInteractor(controller)); - window.GetOpenGlWidget().SetInteractor(interactor); - - controller->FitContent(); - - return a.exec(); -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + +#define GLEW_STATIC 1 +// From Stone +#include "../../Framework/OpenGL/OpenGLIncludes.h" +#include "../../Applications/Sdl/SdlWindow.h" +#include "../../Framework/Scene2D/CairoCompositor.h" +#include "../../Framework/Scene2D/ColorTextureSceneLayer.h" +#include "../../Framework/Scene2D/OpenGLCompositor.h" +#include "../../Framework/Scene2D/PanSceneTracker.h" +#include "../../Framework/Scene2D/RotateSceneTracker.h" +#include "../../Framework/Scene2D/Scene2D.h" +#include "../../Framework/Scene2D/ZoomSceneTracker.h" +#include "../../Framework/Scene2DViewport/ViewportController.h" +#include "../../Framework/Scene2DViewport/UndoStack.h" + +#include "../../Framework/StoneInitialization.h" +#include "../../Framework/Messages/MessageBroker.h" + +// From Orthanc framework +#include +#include +#include +#include +#include + +#include +#include +#include "EmbeddedResources.h" + +#include +#include +#include + +#include "BasicScene.h" + + +using namespace OrthancStone; + + + +static void GLAPIENTRY OpenGLMessageCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam ) +{ + if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) + { + fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", + ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), + type, severity, message ); + } +} + +extern void InitGL(); + +#include +#include "BasicSceneWindow.h" + +int main(int argc, char* argv[]) +{ + QApplication a(argc, argv); + + OrthancStone::Samples::BasicSceneWindow window; + window.show(); + window.GetOpenGlWidget().Init(); + + MessageBroker broker; + boost::shared_ptr undoStack(new UndoStack); + boost::shared_ptr controller = boost::make_shared(undoStack, boost::ref(broker), window.GetOpenGlWidget()); + PrepareScene(controller->GetScene()); + + window.GetOpenGlWidget().GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, + BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1); + + boost::shared_ptr interactor(new BasicScene2DInteractor(controller)); + window.GetOpenGlWidget().SetInteractor(interactor); + + controller->FitContent(); + + return a.exec(); +} diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/MultiPlatform/BasicScene/mainSdl.cpp --- a/Deprecated/Samples/MultiPlatform/BasicScene/mainSdl.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/MultiPlatform/BasicScene/mainSdl.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -1,199 +1,199 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -// From Stone -#include "Framework/Viewport/SdlViewport.h" -#include "Framework/Scene2D/OpenGLCompositor.h" -#include "Framework/Scene2DViewport/UndoStack.h" -#include "Framework/StoneInitialization.h" -#include "Framework/Messages/MessageBroker.h" - -// From Orthanc framework -#include -#include - -#include -#include - -#include -#include - - -#include "BasicScene.h" - -using namespace OrthancStone; - -boost::shared_ptr interactor; - -void HandleApplicationEvent(boost::shared_ptr controller, - const SDL_Event& event) -{ - using namespace OrthancStone; - Scene2D& scene(controller->GetScene()); - if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEMOTION) - { - // TODO: this code is copy/pasted from GuiAdapter::Run() -> find the right place - int scancodeCount = 0; - const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); - bool ctrlPressed(false); - bool shiftPressed(false); - bool altPressed(false); - - if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL]) - ctrlPressed = true; - if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL]) - ctrlPressed = true; - if (SDL_SCANCODE_LSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_LSHIFT]) - shiftPressed = true; - if (SDL_SCANCODE_RSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_RSHIFT]) - shiftPressed = true; - if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT]) - altPressed = true; - - GuiAdapterMouseEvent guiEvent; - ConvertFromPlatform(guiEvent, ctrlPressed, shiftPressed, altPressed, event); - PointerEvent pointerEvent; - pointerEvent.AddPosition(controller->GetViewport().GetPixelCenterCoordinates(event.button.x, event.button.y)); - - interactor->OnMouseEvent(guiEvent, pointerEvent); - return; - } - else if ((event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) && event.key.repeat == 0 /* Ignore key bounce */) - { - GuiAdapterKeyboardEvent guiEvent; - ConvertFromPlatform(guiEvent, event); - - interactor->OnKeyboardEvent(guiEvent); - } - -} - - -static void GLAPIENTRY -OpenGLMessageCallback(GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam ) -{ - if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) - { - fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", - ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), - type, severity, message ); - } -} - - -void Run(boost::shared_ptr controller) -{ - SdlViewport& sdlViewport = dynamic_cast(controller->GetViewport()); - - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(OpenGLMessageCallback, 0); - - controller->GetViewport().GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, - BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1); - - controller->GetViewport().Refresh(); - controller->FitContent(); - - - bool stop = false; - while (!stop) - { - controller->GetViewport().Refresh(); - - SDL_Event event; - while (!stop && - SDL_PollEvent(&event)) - { - if (event.type == SDL_QUIT) - { - stop = true; - break; - } - else if (event.type == SDL_WINDOWEVENT && - event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) - { - sdlViewport.UpdateSize(event.window.data1, event.window.data2); - } - else if (event.type == SDL_KEYDOWN && - event.key.repeat == 0 /* Ignore key bounce */) - { - switch (event.key.keysym.sym) - { - case SDLK_f: - sdlViewport.GetWindow().ToggleMaximize(); - break; - - case SDLK_q: - stop = true; - break; - - default: - break; - } - } - - HandleApplicationEvent(controller, event); - } - - SDL_Delay(1); - } - interactor.reset(); -} - - - - -/** - * IMPORTANT: The full arguments to "main()" are needed for SDL on - * Windows. Otherwise, one gets the linking error "undefined reference - * to `SDL_main'". https://wiki.libsdl.org/FAQWindows - **/ -int main(int argc, char* argv[]) -{ - using namespace OrthancStone; - StoneInitialize(); - Orthanc::Logging::EnableInfoLevel(true); - - try - { - SdlOpenGLViewport viewport("Hello", 1024, 768); - MessageBroker broker; - boost::shared_ptr undoStack(new UndoStack); - boost::shared_ptr controller = boost::make_shared(undoStack, boost::ref(broker), boost::ref(viewport)); - interactor.reset(new BasicScene2DInteractor(controller)); - PrepareScene(controller->GetScene()); - Run(controller); - } - catch (Orthanc::OrthancException& e) - { - LOG(ERROR) << "EXCEPTION: " << e.What(); - } - - StoneFinalize(); - - return 0; -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +// From Stone +#include "Framework/Viewport/SdlViewport.h" +#include "Framework/Scene2D/OpenGLCompositor.h" +#include "Framework/Scene2DViewport/UndoStack.h" +#include "Framework/StoneInitialization.h" +#include "Framework/Messages/MessageBroker.h" + +// From Orthanc framework +#include +#include + +#include +#include + +#include +#include + + +#include "BasicScene.h" + +using namespace OrthancStone; + +boost::shared_ptr interactor; + +void HandleApplicationEvent(boost::shared_ptr controller, + const SDL_Event& event) +{ + using namespace OrthancStone; + Scene2D& scene(controller->GetScene()); + if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEMOTION) + { + // TODO: this code is copy/pasted from GuiAdapter::Run() -> find the right place + int scancodeCount = 0; + const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); + bool ctrlPressed(false); + bool shiftPressed(false); + bool altPressed(false); + + if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL]) + ctrlPressed = true; + if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL]) + ctrlPressed = true; + if (SDL_SCANCODE_LSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_LSHIFT]) + shiftPressed = true; + if (SDL_SCANCODE_RSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_RSHIFT]) + shiftPressed = true; + if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT]) + altPressed = true; + + GuiAdapterMouseEvent guiEvent; + ConvertFromPlatform(guiEvent, ctrlPressed, shiftPressed, altPressed, event); + PointerEvent pointerEvent; + pointerEvent.AddPosition(controller->GetViewport().GetPixelCenterCoordinates(event.button.x, event.button.y)); + + interactor->OnMouseEvent(guiEvent, pointerEvent); + return; + } + else if ((event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) && event.key.repeat == 0 /* Ignore key bounce */) + { + GuiAdapterKeyboardEvent guiEvent; + ConvertFromPlatform(guiEvent, event); + + interactor->OnKeyboardEvent(guiEvent); + } + +} + + +static void GLAPIENTRY +OpenGLMessageCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam ) +{ + if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) + { + fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", + ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), + type, severity, message ); + } +} + + +void Run(boost::shared_ptr controller) +{ + SdlViewport& sdlViewport = dynamic_cast(controller->GetViewport()); + + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(OpenGLMessageCallback, 0); + + controller->GetViewport().GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, + BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1); + + controller->GetViewport().Refresh(); + controller->FitContent(); + + + bool stop = false; + while (!stop) + { + controller->GetViewport().Refresh(); + + SDL_Event event; + while (!stop && + SDL_PollEvent(&event)) + { + if (event.type == SDL_QUIT) + { + stop = true; + break; + } + else if (event.type == SDL_WINDOWEVENT && + event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) + { + sdlViewport.UpdateSize(event.window.data1, event.window.data2); + } + else if (event.type == SDL_KEYDOWN && + event.key.repeat == 0 /* Ignore key bounce */) + { + switch (event.key.keysym.sym) + { + case SDLK_f: + sdlViewport.GetWindow().ToggleMaximize(); + break; + + case SDLK_q: + stop = true; + break; + + default: + break; + } + } + + HandleApplicationEvent(controller, event); + } + + SDL_Delay(1); + } + interactor.reset(); +} + + + + +/** + * IMPORTANT: The full arguments to "main()" are needed for SDL on + * Windows. Otherwise, one gets the linking error "undefined reference + * to `SDL_main'". https://wiki.libsdl.org/FAQWindows + **/ +int main(int argc, char* argv[]) +{ + using namespace OrthancStone; + StoneInitialize(); + Orthanc::Logging::EnableInfoLevel(true); + + try + { + SdlOpenGLViewport viewport("Hello", 1024, 768); + MessageBroker broker; + boost::shared_ptr undoStack(new UndoStack); + boost::shared_ptr controller = boost::make_shared(undoStack, boost::ref(broker), boost::ref(viewport)); + interactor.reset(new BasicScene2DInteractor(controller)); + PrepareScene(controller->GetScene()); + Run(controller); + } + catch (Orthanc::OrthancException& e) + { + LOG(ERROR) << "EXCEPTION: " << e.What(); + } + + StoneFinalize(); + + return 0; +} diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/Qt/QStoneOpenGlWidget.cpp --- a/Deprecated/Samples/Qt/QStoneOpenGlWidget.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/Qt/QStoneOpenGlWidget.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -1,192 +1,192 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "../../Framework/OpenGL/OpenGLIncludes.h" -#include "QStoneOpenGlWidget.h" - -#include - -using namespace OrthancStone; - -void QStoneOpenGlWidget::initializeGL() -{ - glewInit(); -} - -void QStoneOpenGlWidget::MakeCurrent() -{ - this->makeCurrent(); -} - -void QStoneOpenGlWidget::resizeGL(int w, int h) -{ - -} - -void QStoneOpenGlWidget::paintGL() -{ - if (compositor_) - { - compositor_->Refresh(); - } - doneCurrent(); -} - -void ConvertFromPlatform( - OrthancStone::GuiAdapterMouseEvent& guiEvent, - PointerEvent& pointerEvent, - const QMouseEvent& qtEvent, - const IViewport& viewport) -{ - guiEvent.targetX = qtEvent.x(); - guiEvent.targetY = qtEvent.y(); - pointerEvent.AddPosition(viewport.GetPixelCenterCoordinates(guiEvent.targetX, guiEvent.targetY)); - - switch (qtEvent.button()) - { - case Qt::LeftButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_LEFT; break; - case Qt::MiddleButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_MIDDLE; break; - case Qt::RightButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_RIGHT; break; - default: - guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_LEFT; - } - - if (qtEvent.modifiers().testFlag(Qt::ShiftModifier)) - { - guiEvent.shiftKey = true; - } - if (qtEvent.modifiers().testFlag(Qt::ControlModifier)) - { - guiEvent.ctrlKey = true; - } - if (qtEvent.modifiers().testFlag(Qt::AltModifier)) - { - guiEvent.altKey = true; - } -} - -void QStoneOpenGlWidget::mouseEvent(QMouseEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType) -{ - OrthancStone::GuiAdapterMouseEvent guiEvent; - PointerEvent pointerEvent; - ConvertFromPlatform(guiEvent, pointerEvent, *qtEvent, *this); - guiEvent.type = guiEventType; - - if (sceneInteractor_.get() != NULL && compositor_.get() != NULL) - { - sceneInteractor_->OnMouseEvent(guiEvent, pointerEvent); - } - - // force redraw of the OpenGL widget - update(); -} - -void QStoneOpenGlWidget::mousePressEvent(QMouseEvent* qtEvent) -{ - mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEDOWN); -} - -void QStoneOpenGlWidget::mouseMoveEvent(QMouseEvent* qtEvent) -{ - mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEMOVE); -} - -void QStoneOpenGlWidget::mouseReleaseEvent(QMouseEvent* qtEvent) -{ - mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEUP); -} - -void ConvertFromPlatform( - OrthancStone::GuiAdapterKeyboardEvent& guiEvent, - const QKeyEvent& qtEvent) -{ - if (qtEvent.text().length() > 0) - { - guiEvent.sym[0] = qtEvent.text()[0].cell(); - } - else - { - guiEvent.sym[0] = 0; - } - guiEvent.sym[1] = 0; - - if (qtEvent.modifiers().testFlag(Qt::ShiftModifier)) - { - guiEvent.shiftKey = true; - } - if (qtEvent.modifiers().testFlag(Qt::ControlModifier)) - { - guiEvent.ctrlKey = true; - } - if (qtEvent.modifiers().testFlag(Qt::AltModifier)) - { - guiEvent.altKey = true; - } - -} - - -bool QStoneOpenGlWidget::keyEvent(QKeyEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType) -{ - bool handled = false; - OrthancStone::GuiAdapterKeyboardEvent guiEvent; - ConvertFromPlatform(guiEvent, *qtEvent); - guiEvent.type = guiEventType; - - if (sceneInteractor_.get() != NULL && compositor_.get() != NULL) - { - handled = sceneInteractor_->OnKeyboardEvent(guiEvent); - - if (handled) - { - // force redraw of the OpenGL widget - update(); - } - } - return handled; -} - -void QStoneOpenGlWidget::keyPressEvent(QKeyEvent *qtEvent) -{ - bool handled = keyEvent(qtEvent, GUIADAPTER_EVENT_KEYDOWN); - if (!handled) - { - QOpenGLWidget::keyPressEvent(qtEvent); - } -} - -void QStoneOpenGlWidget::keyReleaseEvent(QKeyEvent *qtEvent) -{ - bool handled = keyEvent(qtEvent, GUIADAPTER_EVENT_KEYUP); - if (!handled) - { - QOpenGLWidget::keyPressEvent(qtEvent); - } -} - -void QStoneOpenGlWidget::wheelEvent(QWheelEvent *qtEvent) -{ - OrthancStone::GuiAdapterWheelEvent guiEvent; - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); - - // force redraw of the OpenGL widget - update(); -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "../../Framework/OpenGL/OpenGLIncludes.h" +#include "QStoneOpenGlWidget.h" + +#include + +using namespace OrthancStone; + +void QStoneOpenGlWidget::initializeGL() +{ + glewInit(); +} + +void QStoneOpenGlWidget::MakeCurrent() +{ + this->makeCurrent(); +} + +void QStoneOpenGlWidget::resizeGL(int w, int h) +{ + +} + +void QStoneOpenGlWidget::paintGL() +{ + if (compositor_) + { + compositor_->Refresh(); + } + doneCurrent(); +} + +void ConvertFromPlatform( + OrthancStone::GuiAdapterMouseEvent& guiEvent, + PointerEvent& pointerEvent, + const QMouseEvent& qtEvent, + const IViewport& viewport) +{ + guiEvent.targetX = qtEvent.x(); + guiEvent.targetY = qtEvent.y(); + pointerEvent.AddPosition(viewport.GetPixelCenterCoordinates(guiEvent.targetX, guiEvent.targetY)); + + switch (qtEvent.button()) + { + case Qt::LeftButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_LEFT; break; + case Qt::MiddleButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_MIDDLE; break; + case Qt::RightButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_RIGHT; break; + default: + guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_LEFT; + } + + if (qtEvent.modifiers().testFlag(Qt::ShiftModifier)) + { + guiEvent.shiftKey = true; + } + if (qtEvent.modifiers().testFlag(Qt::ControlModifier)) + { + guiEvent.ctrlKey = true; + } + if (qtEvent.modifiers().testFlag(Qt::AltModifier)) + { + guiEvent.altKey = true; + } +} + +void QStoneOpenGlWidget::mouseEvent(QMouseEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType) +{ + OrthancStone::GuiAdapterMouseEvent guiEvent; + PointerEvent pointerEvent; + ConvertFromPlatform(guiEvent, pointerEvent, *qtEvent, *this); + guiEvent.type = guiEventType; + + if (sceneInteractor_.get() != NULL && compositor_.get() != NULL) + { + sceneInteractor_->OnMouseEvent(guiEvent, pointerEvent); + } + + // force redraw of the OpenGL widget + update(); +} + +void QStoneOpenGlWidget::mousePressEvent(QMouseEvent* qtEvent) +{ + mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEDOWN); +} + +void QStoneOpenGlWidget::mouseMoveEvent(QMouseEvent* qtEvent) +{ + mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEMOVE); +} + +void QStoneOpenGlWidget::mouseReleaseEvent(QMouseEvent* qtEvent) +{ + mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEUP); +} + +void ConvertFromPlatform( + OrthancStone::GuiAdapterKeyboardEvent& guiEvent, + const QKeyEvent& qtEvent) +{ + if (qtEvent.text().length() > 0) + { + guiEvent.sym[0] = qtEvent.text()[0].cell(); + } + else + { + guiEvent.sym[0] = 0; + } + guiEvent.sym[1] = 0; + + if (qtEvent.modifiers().testFlag(Qt::ShiftModifier)) + { + guiEvent.shiftKey = true; + } + if (qtEvent.modifiers().testFlag(Qt::ControlModifier)) + { + guiEvent.ctrlKey = true; + } + if (qtEvent.modifiers().testFlag(Qt::AltModifier)) + { + guiEvent.altKey = true; + } + +} + + +bool QStoneOpenGlWidget::keyEvent(QKeyEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType) +{ + bool handled = false; + OrthancStone::GuiAdapterKeyboardEvent guiEvent; + ConvertFromPlatform(guiEvent, *qtEvent); + guiEvent.type = guiEventType; + + if (sceneInteractor_.get() != NULL && compositor_.get() != NULL) + { + handled = sceneInteractor_->OnKeyboardEvent(guiEvent); + + if (handled) + { + // force redraw of the OpenGL widget + update(); + } + } + return handled; +} + +void QStoneOpenGlWidget::keyPressEvent(QKeyEvent *qtEvent) +{ + bool handled = keyEvent(qtEvent, GUIADAPTER_EVENT_KEYDOWN); + if (!handled) + { + QOpenGLWidget::keyPressEvent(qtEvent); + } +} + +void QStoneOpenGlWidget::keyReleaseEvent(QKeyEvent *qtEvent) +{ + bool handled = keyEvent(qtEvent, GUIADAPTER_EVENT_KEYUP); + if (!handled) + { + QOpenGLWidget::keyPressEvent(qtEvent); + } +} + +void QStoneOpenGlWidget::wheelEvent(QWheelEvent *qtEvent) +{ + OrthancStone::GuiAdapterWheelEvent guiEvent; + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + + // force redraw of the OpenGL widget + update(); +} diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/Qt/QStoneOpenGlWidget.h --- a/Deprecated/Samples/Qt/QStoneOpenGlWidget.h Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/Qt/QStoneOpenGlWidget.h Fri Jun 12 07:19:31 2020 +0200 @@ -1,111 +1,111 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once -#include "../../Framework/OpenGL/OpenGLIncludes.h" -#include -#include -#include - -#include -#include "../../Framework/OpenGL/IOpenGLContext.h" -#include "../../Framework/Scene2D/OpenGLCompositor.h" -#include "../../Framework/Viewport/ViewportBase.h" -#include "../../Applications/Generic/Scene2DInteractor.h" - -namespace OrthancStone -{ - class QStoneOpenGlWidget : - public QOpenGLWidget, - public OpenGL::IOpenGLContext, - public ViewportBase - { - std::unique_ptr compositor_; - boost::shared_ptr sceneInteractor_; - QOpenGLContext openGlContext_; - - public: - QStoneOpenGlWidget(QWidget *parent) : - QOpenGLWidget(parent), - ViewportBase("QtStoneOpenGlWidget") // TODO: we shall be able to define a name but construction time is too early ! - { - setFocusPolicy(Qt::StrongFocus); // to enable keyPressEvent - setMouseTracking(true); // to enable mouseMoveEvent event when no button is pressed - } - - void Init() - { - QSurfaceFormat requestedFormat; - requestedFormat.setVersion( 2, 0 ); - openGlContext_.setFormat( requestedFormat ); - openGlContext_.create(); - openGlContext_.makeCurrent(context()->surface()); - - compositor_.reset(new OpenGLCompositor(*this, GetScene())); - } - - protected: - - //**** QWidget overrides - void initializeGL() override; - void resizeGL(int w, int h) override; - void paintGL() override; - - void mousePressEvent(QMouseEvent* event) override; - void mouseMoveEvent(QMouseEvent* event) override; - void mouseReleaseEvent(QMouseEvent* event) override; - void keyPressEvent(QKeyEvent* event) override; - void keyReleaseEvent(QKeyEvent *event) override; - void wheelEvent(QWheelEvent* event) override; - - //**** IOpenGLContext overrides - - virtual void MakeCurrent() override; - virtual void SwapBuffer() override {} - - virtual unsigned int GetCanvasWidth() const override - { - return this->width(); - } - - virtual unsigned int GetCanvasHeight() const override - { - return this->height(); - } - - public: - - void SetInteractor(boost::shared_ptr sceneInteractor) - { - sceneInteractor_ = sceneInteractor; - } - - virtual ICompositor& GetCompositor() - { - return *compositor_; - } - - protected: - void mouseEvent(QMouseEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType); - bool keyEvent(QKeyEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType); - - }; -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once +#include "../../Framework/OpenGL/OpenGLIncludes.h" +#include +#include +#include + +#include +#include "../../Framework/OpenGL/IOpenGLContext.h" +#include "../../Framework/Scene2D/OpenGLCompositor.h" +#include "../../Framework/Viewport/ViewportBase.h" +#include "../../Applications/Generic/Scene2DInteractor.h" + +namespace OrthancStone +{ + class QStoneOpenGlWidget : + public QOpenGLWidget, + public OpenGL::IOpenGLContext, + public ViewportBase + { + std::unique_ptr compositor_; + boost::shared_ptr sceneInteractor_; + QOpenGLContext openGlContext_; + + public: + QStoneOpenGlWidget(QWidget *parent) : + QOpenGLWidget(parent), + ViewportBase("QtStoneOpenGlWidget") // TODO: we shall be able to define a name but construction time is too early ! + { + setFocusPolicy(Qt::StrongFocus); // to enable keyPressEvent + setMouseTracking(true); // to enable mouseMoveEvent event when no button is pressed + } + + void Init() + { + QSurfaceFormat requestedFormat; + requestedFormat.setVersion( 2, 0 ); + openGlContext_.setFormat( requestedFormat ); + openGlContext_.create(); + openGlContext_.makeCurrent(context()->surface()); + + compositor_.reset(new OpenGLCompositor(*this, GetScene())); + } + + protected: + + //**** QWidget overrides + void initializeGL() override; + void resizeGL(int w, int h) override; + void paintGL() override; + + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void keyPressEvent(QKeyEvent* event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void wheelEvent(QWheelEvent* event) override; + + //**** IOpenGLContext overrides + + virtual void MakeCurrent() override; + virtual void SwapBuffer() override {} + + virtual unsigned int GetCanvasWidth() const override + { + return this->width(); + } + + virtual unsigned int GetCanvasHeight() const override + { + return this->height(); + } + + public: + + void SetInteractor(boost::shared_ptr sceneInteractor) + { + sceneInteractor_ = sceneInteractor; + } + + virtual ICompositor& GetCompositor() + { + return *compositor_; + } + + protected: + void mouseEvent(QMouseEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType); + bool keyEvent(QKeyEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType); + + }; +} diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/Qt/Scene2DInteractor.cpp --- a/Deprecated/Samples/Qt/Scene2DInteractor.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/Qt/Scene2DInteractor.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -1,93 +1,93 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "Scene2DInteractor.h" - -#include "../../Framework/Scene2D/PanSceneTracker.h" -#include "../../Framework/Scene2D/ZoomSceneTracker.h" -#include "../../Framework/Scene2D/RotateSceneTracker.h" - - -namespace OrthancStone -{ - -} - -using namespace OrthancStone; - - -bool BasicScene2DInteractor::OnMouseEvent(const GuiAdapterMouseEvent& event, const PointerEvent& pointerEvent) -{ - if (currentTracker_.get() != NULL) - { - switch (event.type) - { - case GUIADAPTER_EVENT_MOUSEUP: - { - currentTracker_->PointerUp(pointerEvent); - if (!currentTracker_->IsAlive()) - { - currentTracker_.reset(); - } - };break; - case GUIADAPTER_EVENT_MOUSEMOVE: - { - currentTracker_->PointerMove(pointerEvent); - };break; - } - return true; - } - else - { - if (event.button == GUIADAPTER_MOUSEBUTTON_LEFT) - { - currentTracker_.reset(new RotateSceneTracker(viewportController_, pointerEvent)); - } - else if (event.button == GUIADAPTER_MOUSEBUTTON_MIDDLE) - { - currentTracker_.reset(new PanSceneTracker(viewportController_, pointerEvent)); - } - else if (event.button == GUIADAPTER_MOUSEBUTTON_RIGHT && compositor_.get() != NULL) - { - currentTracker_.reset(new ZoomSceneTracker(viewportController_, pointerEvent, compositor_->GetHeight())); - } - return true; - } - return false; -} - -bool BasicScene2DInteractor::OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent) -{ - switch (guiEvent.sym[0]) - { - case 's': - { - viewportController_->FitContent(compositor_->GetWidth(), compositor_->GetHeight()); - return true; - }; - } - return false; -} - -bool BasicScene2DInteractor::OnWheelEvent(const GuiAdapterWheelEvent& guiEvent) -{ - return false; -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "Scene2DInteractor.h" + +#include "../../Framework/Scene2D/PanSceneTracker.h" +#include "../../Framework/Scene2D/ZoomSceneTracker.h" +#include "../../Framework/Scene2D/RotateSceneTracker.h" + + +namespace OrthancStone +{ + +} + +using namespace OrthancStone; + + +bool BasicScene2DInteractor::OnMouseEvent(const GuiAdapterMouseEvent& event, const PointerEvent& pointerEvent) +{ + if (currentTracker_.get() != NULL) + { + switch (event.type) + { + case GUIADAPTER_EVENT_MOUSEUP: + { + currentTracker_->PointerUp(pointerEvent); + if (!currentTracker_->IsAlive()) + { + currentTracker_.reset(); + } + };break; + case GUIADAPTER_EVENT_MOUSEMOVE: + { + currentTracker_->PointerMove(pointerEvent); + };break; + } + return true; + } + else + { + if (event.button == GUIADAPTER_MOUSEBUTTON_LEFT) + { + currentTracker_.reset(new RotateSceneTracker(viewportController_, pointerEvent)); + } + else if (event.button == GUIADAPTER_MOUSEBUTTON_MIDDLE) + { + currentTracker_.reset(new PanSceneTracker(viewportController_, pointerEvent)); + } + else if (event.button == GUIADAPTER_MOUSEBUTTON_RIGHT && compositor_.get() != NULL) + { + currentTracker_.reset(new ZoomSceneTracker(viewportController_, pointerEvent, compositor_->GetHeight())); + } + return true; + } + return false; +} + +bool BasicScene2DInteractor::OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent) +{ + switch (guiEvent.sym[0]) + { + case 's': + { + viewportController_->FitContent(compositor_->GetWidth(), compositor_->GetHeight()); + return true; + }; + } + return false; +} + +bool BasicScene2DInteractor::OnWheelEvent(const GuiAdapterWheelEvent& guiEvent) +{ + return false; +} diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/Qt/Scene2DInteractor.h --- a/Deprecated/Samples/Qt/Scene2DInteractor.h Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/Qt/Scene2DInteractor.h Fri Jun 12 07:19:31 2020 +0200 @@ -1,40 +1,40 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "../../Applications/Generic/Scene2DInteractor.h" -#include "../../Framework/Scene2DViewport/IFlexiblePointerTracker.h" - - -class BasicScene2DInteractor : public OrthancStone::Scene2DInteractor -{ - boost::shared_ptr currentTracker_; -public: - BasicScene2DInteractor(boost::shared_ptr viewportController) : - Scene2DInteractor(viewportController) - {} - - virtual bool OnMouseEvent(const OrthancStone::GuiAdapterMouseEvent& event, const OrthancStone::PointerEvent& pointerEvent) override; - virtual bool OnKeyboardEvent(const OrthancStone::GuiAdapterKeyboardEvent& guiEvent); - virtual bool OnWheelEvent(const OrthancStone::GuiAdapterWheelEvent& guiEvent); -}; - +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "../../Applications/Generic/Scene2DInteractor.h" +#include "../../Framework/Scene2DViewport/IFlexiblePointerTracker.h" + + +class BasicScene2DInteractor : public OrthancStone::Scene2DInteractor +{ + boost::shared_ptr currentTracker_; +public: + BasicScene2DInteractor(boost::shared_ptr viewportController) : + Scene2DInteractor(viewportController) + {} + + virtual bool OnMouseEvent(const OrthancStone::GuiAdapterMouseEvent& event, const OrthancStone::PointerEvent& pointerEvent) override; + virtual bool OnKeyboardEvent(const OrthancStone::GuiAdapterKeyboardEvent& guiEvent); + virtual bool OnWheelEvent(const OrthancStone::GuiAdapterWheelEvent& guiEvent); +}; + diff -r b17d03599726 -r 182bf3106ee2 Deprecated/Samples/Sdl/RadiographyEditor.cpp --- a/Deprecated/Samples/Sdl/RadiographyEditor.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Deprecated/Samples/Sdl/RadiographyEditor.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -1,267 +1,267 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - -#include "../Shared/RadiographyEditorApp.h" - -// From Stone -#include "../../Framework/Oracle/SleepOracleCommand.h" -#include "../../Framework/Oracle/ThreadedOracle.h" -#include "../../Applications/Sdl/SdlOpenGLWindow.h" -#include "../../Framework/Scene2D/OpenGLCompositor.h" -#include "../../Framework/Scene2D/CairoCompositor.h" -#include "../../Framework/Scene2D/ColorTextureSceneLayer.h" -#include "../../Framework/Scene2D/OpenGLCompositor.h" -#include "../../Framework/StoneInitialization.h" - -#include -#include - - -#include -#include - -#include -#include - -using namespace OrthancStone; - -namespace OrthancStone -{ - class NativeApplicationContext : public IMessageEmitter - { - private: - boost::shared_mutex mutex_; - MessageBroker broker_; - IObservable oracleObservable_; - - public: - NativeApplicationContext() : - oracleObservable_(broker_) - { - } - - - virtual void EmitMessage(const IObserver& observer, - const IMessage& message) ORTHANC_OVERRIDE - { - try - { - boost::unique_lock lock(mutex_); - oracleObservable_.EmitMessage(observer, message); - } - catch (Orthanc::OrthancException& e) - { - LOG(ERROR) << "Exception while emitting a message: " << e.What(); - } - } - - - class ReaderLock : public boost::noncopyable - { - private: - NativeApplicationContext& that_; - boost::shared_lock lock_; - - public: - ReaderLock(NativeApplicationContext& that) : - that_(that), - lock_(that.mutex_) - { - } - }; - - - class WriterLock : public boost::noncopyable - { - private: - NativeApplicationContext& that_; - boost::unique_lock lock_; - - public: - WriterLock(NativeApplicationContext& that) : - that_(that), - lock_(that.mutex_) - { - } - - MessageBroker& GetBroker() - { - return that_.broker_; - } - - IObservable& GetOracleObservable() - { - return that_.oracleObservable_; - } - }; - }; -} - -class OpenGlSdlCompositorFactory : public ICompositorFactory -{ - OpenGL::IOpenGLContext& openGlContext_; - -public: - OpenGlSdlCompositorFactory(OpenGL::IOpenGLContext& openGlContext) : - openGlContext_(openGlContext) - {} - - ICompositor* GetCompositor(const Scene2D& scene) - { - - OpenGLCompositor* compositor = new OpenGLCompositor(openGlContext_, scene); - compositor->SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, - FONT_SIZE_0, Orthanc::Encoding_Latin1); - compositor->SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT, - FONT_SIZE_1, Orthanc::Encoding_Latin1); - return compositor; - } -}; - -static void GLAPIENTRY -OpenGLMessageCallback(GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam) -{ - if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) - { - fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", - (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), - type, severity, message); - } -} - - -/** - * IMPORTANT: The full arguments to "main()" are needed for SDL on - * Windows. Otherwise, one gets the linking error "undefined reference - * to `SDL_main'". https://wiki.libsdl.org/FAQWindows - **/ -int main(int argc, char* argv[]) -{ - using namespace OrthancStone; - - StoneInitialize(); - Orthanc::Logging::EnableInfoLevel(true); - // Orthanc::Logging::EnableTraceLevel(true); - - try - { - OrthancStone::NativeApplicationContext context; - OrthancStone::NativeApplicationContext::WriterLock lock(context); - OrthancStone::ThreadedOracle oracle(context); - - // False means we do NOT let Windows treat this as a legacy application - // that needs to be scaled - SdlOpenGLWindow window("Hello", 1024, 1024, false); - - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(OpenGLMessageCallback, 0); - - std::unique_ptr compositorFactory(new OpenGlSdlCompositorFactory(window)); - boost::shared_ptr app(new RadiographyEditorApp(oracle, lock.GetOracleObservable(), compositorFactory.release())); - app->PrepareScene(); - app->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); - - bool stopApplication = false; - - while (!stopApplication) - { - app->Refresh(); - - SDL_Event event; - while (!stopApplication && SDL_PollEvent(&event)) - { - OrthancStone::KeyboardModifiers modifiers = OrthancStone::KeyboardModifiers_None; - if (event.key.keysym.mod & KMOD_CTRL) - modifiers = static_cast(static_cast(modifiers) | static_cast(OrthancStone::KeyboardModifiers_Control)); - if (event.key.keysym.mod & KMOD_ALT) - modifiers = static_cast(static_cast(modifiers) | static_cast(OrthancStone::KeyboardModifiers_Alt)); - if (event.key.keysym.mod & KMOD_SHIFT) - modifiers = static_cast(static_cast(modifiers) | static_cast(OrthancStone::KeyboardModifiers_Shift)); - - OrthancStone::MouseButton button; - if (event.button.button == SDL_BUTTON_LEFT) - button = OrthancStone::MouseButton_Left; - else if (event.button.button == SDL_BUTTON_MIDDLE) - button = OrthancStone::MouseButton_Middle; - else if (event.button.button == SDL_BUTTON_RIGHT) - button = OrthancStone::MouseButton_Right; - - if (event.type == SDL_QUIT) - { - stopApplication = true; - break; - } - else if (event.type == SDL_WINDOWEVENT && - event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) - { - app->DisableTracker(); // was: tracker.reset(NULL); - app->UpdateSize(); - } - else if (event.type == SDL_KEYDOWN && - event.key.repeat == 0 /* Ignore key bounce */) - { - switch (event.key.keysym.sym) - { - case SDLK_f: - window.GetWindow().ToggleMaximize(); - break; - - case SDLK_q: - stopApplication = true; - break; - default: - { - app->OnKeyPressed(event.key.keysym.sym, modifiers); - } - } - } - else if (event.type == SDL_MOUSEBUTTONDOWN) - { - app->OnMouseDown(event.button.x, event.button.y, modifiers, button); - } - else if (event.type == SDL_MOUSEMOTION) - { - app->OnMouseMove(event.button.x, event.button.y, modifiers); - } - else if (event.type == SDL_MOUSEBUTTONUP) - { - app->OnMouseUp(event.button.x, event.button.y, modifiers, button); - } - } - SDL_Delay(1); - } - } - catch (Orthanc::OrthancException& e) - { - LOG(ERROR) << "EXCEPTION: " << e.What(); - } - - StoneFinalize(); - - return 0; -} - - +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + +#include "../Shared/RadiographyEditorApp.h" + +// From Stone +#include "../../Framework/Oracle/SleepOracleCommand.h" +#include "../../Framework/Oracle/ThreadedOracle.h" +#include "../../Applications/Sdl/SdlOpenGLWindow.h" +#include "../../Framework/Scene2D/OpenGLCompositor.h" +#include "../../Framework/Scene2D/CairoCompositor.h" +#include "../../Framework/Scene2D/ColorTextureSceneLayer.h" +#include "../../Framework/Scene2D/OpenGLCompositor.h" +#include "../../Framework/StoneInitialization.h" + +#include +#include + + +#include +#include + +#include +#include + +using namespace OrthancStone; + +namespace OrthancStone +{ + class NativeApplicationContext : public IMessageEmitter + { + private: + boost::shared_mutex mutex_; + MessageBroker broker_; + IObservable oracleObservable_; + + public: + NativeApplicationContext() : + oracleObservable_(broker_) + { + } + + + virtual void EmitMessage(const IObserver& observer, + const IMessage& message) ORTHANC_OVERRIDE + { + try + { + boost::unique_lock lock(mutex_); + oracleObservable_.EmitMessage(observer, message); + } + catch (Orthanc::OrthancException& e) + { + LOG(ERROR) << "Exception while emitting a message: " << e.What(); + } + } + + + class ReaderLock : public boost::noncopyable + { + private: + NativeApplicationContext& that_; + boost::shared_lock lock_; + + public: + ReaderLock(NativeApplicationContext& that) : + that_(that), + lock_(that.mutex_) + { + } + }; + + + class WriterLock : public boost::noncopyable + { + private: + NativeApplicationContext& that_; + boost::unique_lock lock_; + + public: + WriterLock(NativeApplicationContext& that) : + that_(that), + lock_(that.mutex_) + { + } + + MessageBroker& GetBroker() + { + return that_.broker_; + } + + IObservable& GetOracleObservable() + { + return that_.oracleObservable_; + } + }; + }; +} + +class OpenGlSdlCompositorFactory : public ICompositorFactory +{ + OpenGL::IOpenGLContext& openGlContext_; + +public: + OpenGlSdlCompositorFactory(OpenGL::IOpenGLContext& openGlContext) : + openGlContext_(openGlContext) + {} + + ICompositor* GetCompositor(const Scene2D& scene) + { + + OpenGLCompositor* compositor = new OpenGLCompositor(openGlContext_, scene); + compositor->SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, + FONT_SIZE_0, Orthanc::Encoding_Latin1); + compositor->SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT, + FONT_SIZE_1, Orthanc::Encoding_Latin1); + return compositor; + } +}; + +static void GLAPIENTRY +OpenGLMessageCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) +{ + if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) + { + fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", + (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), + type, severity, message); + } +} + + +/** + * IMPORTANT: The full arguments to "main()" are needed for SDL on + * Windows. Otherwise, one gets the linking error "undefined reference + * to `SDL_main'". https://wiki.libsdl.org/FAQWindows + **/ +int main(int argc, char* argv[]) +{ + using namespace OrthancStone; + + StoneInitialize(); + Orthanc::Logging::EnableInfoLevel(true); + // Orthanc::Logging::EnableTraceLevel(true); + + try + { + OrthancStone::NativeApplicationContext context; + OrthancStone::NativeApplicationContext::WriterLock lock(context); + OrthancStone::ThreadedOracle oracle(context); + + // False means we do NOT let Windows treat this as a legacy application + // that needs to be scaled + SdlOpenGLWindow window("Hello", 1024, 1024, false); + + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(OpenGLMessageCallback, 0); + + std::unique_ptr compositorFactory(new OpenGlSdlCompositorFactory(window)); + boost::shared_ptr app(new RadiographyEditorApp(oracle, lock.GetOracleObservable(), compositorFactory.release())); + app->PrepareScene(); + app->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); + + bool stopApplication = false; + + while (!stopApplication) + { + app->Refresh(); + + SDL_Event event; + while (!stopApplication && SDL_PollEvent(&event)) + { + OrthancStone::KeyboardModifiers modifiers = OrthancStone::KeyboardModifiers_None; + if (event.key.keysym.mod & KMOD_CTRL) + modifiers = static_cast(static_cast(modifiers) | static_cast(OrthancStone::KeyboardModifiers_Control)); + if (event.key.keysym.mod & KMOD_ALT) + modifiers = static_cast(static_cast(modifiers) | static_cast(OrthancStone::KeyboardModifiers_Alt)); + if (event.key.keysym.mod & KMOD_SHIFT) + modifiers = static_cast(static_cast(modifiers) | static_cast(OrthancStone::KeyboardModifiers_Shift)); + + OrthancStone::MouseButton button; + if (event.button.button == SDL_BUTTON_LEFT) + button = OrthancStone::MouseButton_Left; + else if (event.button.button == SDL_BUTTON_MIDDLE) + button = OrthancStone::MouseButton_Middle; + else if (event.button.button == SDL_BUTTON_RIGHT) + button = OrthancStone::MouseButton_Right; + + if (event.type == SDL_QUIT) + { + stopApplication = true; + break; + } + else if (event.type == SDL_WINDOWEVENT && + event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) + { + app->DisableTracker(); // was: tracker.reset(NULL); + app->UpdateSize(); + } + else if (event.type == SDL_KEYDOWN && + event.key.repeat == 0 /* Ignore key bounce */) + { + switch (event.key.keysym.sym) + { + case SDLK_f: + window.GetWindow().ToggleMaximize(); + break; + + case SDLK_q: + stopApplication = true; + break; + default: + { + app->OnKeyPressed(event.key.keysym.sym, modifiers); + } + } + } + else if (event.type == SDL_MOUSEBUTTONDOWN) + { + app->OnMouseDown(event.button.x, event.button.y, modifiers, button); + } + else if (event.type == SDL_MOUSEMOTION) + { + app->OnMouseMove(event.button.x, event.button.y, modifiers); + } + else if (event.type == SDL_MOUSEBUTTONUP) + { + app->OnMouseUp(event.button.x, event.button.y, modifiers, button); + } + } + SDL_Delay(1); + } + } + catch (Orthanc::OrthancException& e) + { + LOG(ERROR) << "EXCEPTION: " << e.What(); + } + + StoneFinalize(); + + return 0; +} + + diff -r b17d03599726 -r 182bf3106ee2 Framework/Deprecated/Loaders/DicomStructureSetLoader2.cpp --- a/Framework/Deprecated/Loaders/DicomStructureSetLoader2.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Framework/Deprecated/Loaders/DicomStructureSetLoader2.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -28,7 +28,7 @@ namespace Deprecated { - + DicomStructureSetLoader2::DicomStructureSetLoader2( DicomStructureSet2& structureSet , IOracle& oracle @@ -45,10 +45,10 @@ oracleObservable.RegisterObserverCallback( new Callable (*this, &DicomStructureSetLoader2::HandleSuccessMessage)); - + oracleObservable.RegisterObserverCallback( new Callable - (*this, &DicomStructureSetLoader2::HandleExceptionMessage)); + (*this, &DicomStructureSetLoader2::HandleExceptionMessage)); } DicomStructureSetLoader2::~DicomStructureSetLoader2() @@ -99,27 +99,27 @@ { return structuresReady_; } - - /* - + + /* + void LoaderStateMachine::HandleExceptionMessage(const OracleCommandExceptionMessage& message) { LOG(ERROR) << "LoaderStateMachine::HandleExceptionMessage: error in the state machine, stopping all processing"; LOG(ERROR) << "Error: " << message.GetException().What() << " Details: " << message.GetException().GetDetails(); Clear(); - } - + } + LoaderStateMachine::~LoaderStateMachine() { Clear(); } - - - */ - -} - + + + */ + +} + #endif // BGO_ENABLE_DICOMSTRUCTURESETLOADER2 diff -r b17d03599726 -r 182bf3106ee2 Framework/Toolbox/DicomStructurePolygon2.cpp --- a/Framework/Toolbox/DicomStructurePolygon2.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Framework/Toolbox/DicomStructurePolygon2.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -185,10 +185,10 @@ // alpha = (v2-planeV)/(v2-v1) // because the following two triangles are similar // [ (planeY,x) , (y2,x2), (planeY,x2) ] or - // [ (planeX,y) , (x2,y2), (planeX,y2) ] + // [ (planeX,y) , (x2,y2), (planeX,y2) ] // and // [ (y1 ,x1) , (y2,x2), (y1 ,x2) ] or - // [ (x1 ,y1) , (x2,y2), (x1 ,y2) ] + // [ (x1 ,y1) , (x2,y2), (x1 ,y2) ] /* void CoordinateSystem3D::ProjectPoint(double& offsetX, @@ -218,7 +218,7 @@ // we consider that the x axis is always parallel to the polygons // TODO: is this hypothesis safe?????? - uIntersections.insert(std::lower_bound(uIntersections.begin(), uIntersections.end(), xi), xi); + uIntersections.insert(std::lower_bound(uIntersections.begin(), uIntersections.end(), xi), xi); } } } diff -r b17d03599726 -r 182bf3106ee2 Framework/Toolbox/DicomStructureSetUtils.cpp --- a/Framework/Toolbox/DicomStructureSetUtils.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Framework/Toolbox/DicomStructureSetUtils.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -76,19 +76,19 @@ /* - compute list of segments : - - numberOfRectsFromHereOn = 0 - possibleNext = {in_k,in_kplus1} - - for all boundaries: - - we create a vertical segment and we push it - - if boundary is a start, numberOfRectsFromHereOn += 1. - - if we switch from 0 to 1, we start a segment - - if we switch from 1 to 2, we end the current segment and we record it - - if boundary is an end, numberOfRectsFromHereOn -= 1. - - if we switch from 1 to 0, we end the current segment and we record it - - if we switch from 2 to 1, we start a segment + compute list of segments : + + numberOfRectsFromHereOn = 0 + possibleNext = {in_k,in_kplus1} + + for all boundaries: + - we create a vertical segment and we push it + - if boundary is a start, numberOfRectsFromHereOn += 1. + - if we switch from 0 to 1, we start a segment + - if we switch from 1 to 2, we end the current segment and we record it + - if boundary is an end, numberOfRectsFromHereOn -= 1. + - if we switch from 1 to 0, we end the current segment and we record it + - if we switch from 2 to 1, we start a segment */ // static @@ -104,11 +104,11 @@ const RtStructRectangleInSlab& rect = slab[iRect]; { std::pair boundary(rect.xmin, RectangleBoundaryKind_Start); - boundaries.insert(std::lower_bound(boundaries.begin(), boundaries.end(), boundary), boundary); + boundaries.insert(std::lower_bound(boundaries.begin(), boundaries.end(), boundary), boundary); } { std::pair boundary(rect.xmax, RectangleBoundaryKind_End); - boundaries.insert(std::lower_bound(boundaries.begin(), boundaries.end(), boundary), boundary); + boundaries.insert(std::lower_bound(boundaries.begin(), boundaries.end(), boundary), boundary); } } } diff -r b17d03599726 -r 182bf3106ee2 Framework/Toolbox/TextRenderer.cpp --- a/Framework/Toolbox/TextRenderer.cpp Fri Jun 12 07:18:07 2020 +0200 +++ b/Framework/Toolbox/TextRenderer.cpp Fri Jun 12 07:19:31 2020 +0200 @@ -1,136 +1,136 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "TextRenderer.h" - -#include "../Scene2D/CairoCompositor.h" -#include "../Scene2D/ColorTextureSceneLayer.h" -#include "../Scene2D/FloatTextureSceneLayer.h" -#include "../Scene2D/TextSceneLayer.h" -#include "../Fonts/GlyphBitmapAlphabet.h" -#include "../Fonts/FontRenderer.h" - -#include -#include -#include -#include - -namespace OrthancStone -{ - Orthanc::ImageAccessor* TextRenderer::Render(Orthanc::EmbeddedResources::FileResourceId font, - unsigned int fontSize, - const std::string& utf8String - ) - { - FontRenderer renderer; - renderer.LoadFont(font, fontSize); - - // add each char to be rendered to the alphabet - std::unique_ptr alphabet(new GlyphBitmapAlphabet); - - size_t posInString = 0; - uint32_t unicode; - size_t utf8CharLength; - - while (posInString < utf8String.size()) - { - Orthanc::Toolbox::Utf8ToUnicodeCharacter(unicode, utf8CharLength, utf8String, posInString); - alphabet->AddUnicodeCharacter(renderer, unicode); - posInString += utf8CharLength; - } - - - std::unique_ptr renderedText(alphabet->RenderText(utf8String)); - - // add a blank line on top of the text (to improve bilinear filtering of the topmost line) - std::unique_ptr renderedTextExtended(new Orthanc::Image(renderedText->GetFormat(), renderedText->GetWidth(), renderedText->GetHeight() + 1, true)); - - Orthanc::ImageAccessor textRegion; - Orthanc::ImageAccessor firstLineRegion; - - renderedTextExtended->GetRegion(firstLineRegion, 0, 0, renderedText->GetWidth(), 1); - Orthanc::ImageProcessing::Set(firstLineRegion, 0); - - renderedTextExtended->GetRegion(textRegion, 0, 1, renderedText->GetWidth(), renderedText->GetHeight()); - Orthanc::ImageProcessing::Copy(textRegion, *renderedText); - - return renderedTextExtended.release(); - } - - - Orthanc::ImageAccessor* TextRenderer::RenderWithAlpha(Orthanc::EmbeddedResources::FileResourceId resource, - unsigned int fontSize, - const std::string& utf8String, - uint8_t foreground) - { - std::unique_ptr renderedText8(Render(resource, fontSize, utf8String)); - std::unique_ptr target(new Orthanc::Image(Orthanc::PixelFormat_RGBA32, renderedText8->GetWidth(), renderedText8->GetHeight(), true)); - - Orthanc::ImageProcessing::Set(*target, foreground, foreground, foreground, *renderedText8); - return target.release(); - } - - - // currently disabled because the background is actually not transparent once we use the Cairo Compositor ! - // - // // renders text in color + a border with alpha in a RGBA32 image - // Orthanc::ImageAccessor* TextRenderer::RenderWithAlpha(Orthanc::EmbeddedResources::FileResourceId resource, - // unsigned int fontSize, - // const std::string& utf8String, - // uint8_t foreground, - // uint8_t borderColor) - // { - // std::unique_ptr renderedBorderAlpha(RenderWithAlpha(resource, fontSize, utf8String, borderColor)); - // std::unique_ptr renderedTextAlpha(RenderWithAlpha(resource, fontSize, utf8String, foreground)); - - // unsigned int textWidth = renderedBorderAlpha->GetWidth(); - // unsigned int textHeight = renderedBorderAlpha->GetHeight(); - - // Scene2D targetScene; - // std::unique_ptr borderLayerLeft(new ColorTextureSceneLayer(*renderedBorderAlpha)); - // std::unique_ptr borderLayerRight(new ColorTextureSceneLayer(*renderedBorderAlpha)); - // std::unique_ptr borderLayerTop(new ColorTextureSceneLayer(*renderedBorderAlpha)); - // std::unique_ptr borderLayerBottom(new ColorTextureSceneLayer(*renderedBorderAlpha)); - // std::unique_ptr textLayerCenter(new ColorTextureSceneLayer(*renderedTextAlpha)); - - // borderLayerLeft->SetOrigin(0, 1); - // borderLayerRight->SetOrigin(2, 1); - // borderLayerTop->SetOrigin(1, 0); - // borderLayerBottom->SetOrigin(1, 2); - // textLayerCenter->SetOrigin(1, 1); - // targetScene.SetLayer(1, borderLayerLeft.release()); - // targetScene.SetLayer(2, borderLayerRight.release()); - // targetScene.SetLayer(3, borderLayerTop.release()); - // targetScene.SetLayer(4, borderLayerBottom.release()); - // targetScene.SetLayer(5, textLayerCenter.release()); - - // targetScene.FitContent(textWidth + 2, textHeight + 2); - // CairoCompositor compositor(targetScene, textWidth + 2, textHeight + 2); - // compositor.Refresh(); - - // Orthanc::ImageAccessor canvas; - // compositor.GetCanvas().GetReadOnlyAccessor(canvas); - - // std::unique_ptr output(new Orthanc::Image(Orthanc::PixelFormat_RGBA32, canvas.GetWidth(), canvas.GetHeight(), false)); - // Orthanc::ImageProcessing::Convert(*output, canvas); - // return output.release(); - // } -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "TextRenderer.h" + +#include "../Scene2D/CairoCompositor.h" +#include "../Scene2D/ColorTextureSceneLayer.h" +#include "../Scene2D/FloatTextureSceneLayer.h" +#include "../Scene2D/TextSceneLayer.h" +#include "../Fonts/GlyphBitmapAlphabet.h" +#include "../Fonts/FontRenderer.h" + +#include +#include +#include +#include + +namespace OrthancStone +{ + Orthanc::ImageAccessor* TextRenderer::Render(Orthanc::EmbeddedResources::FileResourceId font, + unsigned int fontSize, + const std::string& utf8String + ) + { + FontRenderer renderer; + renderer.LoadFont(font, fontSize); + + // add each char to be rendered to the alphabet + std::unique_ptr alphabet(new GlyphBitmapAlphabet); + + size_t posInString = 0; + uint32_t unicode; + size_t utf8CharLength; + + while (posInString < utf8String.size()) + { + Orthanc::Toolbox::Utf8ToUnicodeCharacter(unicode, utf8CharLength, utf8String, posInString); + alphabet->AddUnicodeCharacter(renderer, unicode); + posInString += utf8CharLength; + } + + + std::unique_ptr renderedText(alphabet->RenderText(utf8String)); + + // add a blank line on top of the text (to improve bilinear filtering of the topmost line) + std::unique_ptr renderedTextExtended(new Orthanc::Image(renderedText->GetFormat(), renderedText->GetWidth(), renderedText->GetHeight() + 1, true)); + + Orthanc::ImageAccessor textRegion; + Orthanc::ImageAccessor firstLineRegion; + + renderedTextExtended->GetRegion(firstLineRegion, 0, 0, renderedText->GetWidth(), 1); + Orthanc::ImageProcessing::Set(firstLineRegion, 0); + + renderedTextExtended->GetRegion(textRegion, 0, 1, renderedText->GetWidth(), renderedText->GetHeight()); + Orthanc::ImageProcessing::Copy(textRegion, *renderedText); + + return renderedTextExtended.release(); + } + + + Orthanc::ImageAccessor* TextRenderer::RenderWithAlpha(Orthanc::EmbeddedResources::FileResourceId resource, + unsigned int fontSize, + const std::string& utf8String, + uint8_t foreground) + { + std::unique_ptr renderedText8(Render(resource, fontSize, utf8String)); + std::unique_ptr target(new Orthanc::Image(Orthanc::PixelFormat_RGBA32, renderedText8->GetWidth(), renderedText8->GetHeight(), true)); + + Orthanc::ImageProcessing::Set(*target, foreground, foreground, foreground, *renderedText8); + return target.release(); + } + + + // currently disabled because the background is actually not transparent once we use the Cairo Compositor ! + // + // // renders text in color + a border with alpha in a RGBA32 image + // Orthanc::ImageAccessor* TextRenderer::RenderWithAlpha(Orthanc::EmbeddedResources::FileResourceId resource, + // unsigned int fontSize, + // const std::string& utf8String, + // uint8_t foreground, + // uint8_t borderColor) + // { + // std::unique_ptr renderedBorderAlpha(RenderWithAlpha(resource, fontSize, utf8String, borderColor)); + // std::unique_ptr renderedTextAlpha(RenderWithAlpha(resource, fontSize, utf8String, foreground)); + + // unsigned int textWidth = renderedBorderAlpha->GetWidth(); + // unsigned int textHeight = renderedBorderAlpha->GetHeight(); + + // Scene2D targetScene; + // std::unique_ptr borderLayerLeft(new ColorTextureSceneLayer(*renderedBorderAlpha)); + // std::unique_ptr borderLayerRight(new ColorTextureSceneLayer(*renderedBorderAlpha)); + // std::unique_ptr borderLayerTop(new ColorTextureSceneLayer(*renderedBorderAlpha)); + // std::unique_ptr borderLayerBottom(new ColorTextureSceneLayer(*renderedBorderAlpha)); + // std::unique_ptr textLayerCenter(new ColorTextureSceneLayer(*renderedTextAlpha)); + + // borderLayerLeft->SetOrigin(0, 1); + // borderLayerRight->SetOrigin(2, 1); + // borderLayerTop->SetOrigin(1, 0); + // borderLayerBottom->SetOrigin(1, 2); + // textLayerCenter->SetOrigin(1, 1); + // targetScene.SetLayer(1, borderLayerLeft.release()); + // targetScene.SetLayer(2, borderLayerRight.release()); + // targetScene.SetLayer(3, borderLayerTop.release()); + // targetScene.SetLayer(4, borderLayerBottom.release()); + // targetScene.SetLayer(5, textLayerCenter.release()); + + // targetScene.FitContent(textWidth + 2, textHeight + 2); + // CairoCompositor compositor(targetScene, textWidth + 2, textHeight + 2); + // compositor.Refresh(); + + // Orthanc::ImageAccessor canvas; + // compositor.GetCanvas().GetReadOnlyAccessor(canvas); + + // std::unique_ptr output(new Orthanc::Image(Orthanc::PixelFormat_RGBA32, canvas.GetWidth(), canvas.GetHeight(), false)); + // Orthanc::ImageProcessing::Convert(*output, canvas); + // return output.release(); + // } +} diff -r b17d03599726 -r 182bf3106ee2 Framework/Toolbox/TextRenderer.h --- a/Framework/Toolbox/TextRenderer.h Fri Jun 12 07:18:07 2020 +0200 +++ b/Framework/Toolbox/TextRenderer.h Fri Jun 12 07:19:31 2020 +0200 @@ -1,53 +1,53 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2020 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include -#include - -namespace OrthancStone -{ - // Helpers methods to render text in bitmaps. - // Compared to the GlyphBitmapAlphabet::RenderText, these methods do not need a - // code page. - class TextRenderer : public boost::noncopyable - { - public: - // simply renders text in GrayScale8 with a black background and a white text - static Orthanc::ImageAccessor* Render(Orthanc::EmbeddedResources::FileResourceId resource, - unsigned int fontSize, - const std::string& utf8String); - - // renders text in "color" with alpha in a RGBA32 image - static Orthanc::ImageAccessor* RenderWithAlpha(Orthanc::EmbeddedResources::FileResourceId resource, - unsigned int fontSize, - const std::string& utf8String, - uint8_t foreground); - - // // renders text in color + a border with alpha in a RGBA32 image - // static Orthanc::ImageAccessor* RenderWithAlpha(Orthanc::EmbeddedResources::FileResourceId resource, - // unsigned int fontSize, - // const std::string& utf8String, - // uint8_t foreground, - // uint8_t borderColor); - }; -} +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include +#include + +namespace OrthancStone +{ + // Helpers methods to render text in bitmaps. + // Compared to the GlyphBitmapAlphabet::RenderText, these methods do not need a + // code page. + class TextRenderer : public boost::noncopyable + { + public: + // simply renders text in GrayScale8 with a black background and a white text + static Orthanc::ImageAccessor* Render(Orthanc::EmbeddedResources::FileResourceId resource, + unsigned int fontSize, + const std::string& utf8String); + + // renders text in "color" with alpha in a RGBA32 image + static Orthanc::ImageAccessor* RenderWithAlpha(Orthanc::EmbeddedResources::FileResourceId resource, + unsigned int fontSize, + const std::string& utf8String, + uint8_t foreground); + + // // renders text in color + a border with alpha in a RGBA32 image + // static Orthanc::ImageAccessor* RenderWithAlpha(Orthanc::EmbeddedResources::FileResourceId resource, + // unsigned int fontSize, + // const std::string& utf8String, + // uint8_t foreground, + // uint8_t borderColor); + }; +}