# HG changeset patch # User Benjamin Golinvaux # Date 1553003026 -3600 # Node ID d785ee57bd950f392b22898c05c4663331c0b564 # Parent 1c5104a6f7e430f61b42ec1f6b8ae41105770b3c# Parent f65748b33bd1a45e72b55299efd7c91cbe161570 Merge from bgo-commands-codegen diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Commands/BaseCommandBuilder.cpp --- a/Applications/Commands/BaseCommandBuilder.cpp Mon Mar 18 16:01:07 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 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 "BaseCommandBuilder.h" -#include "Core/OrthancException.h" -#include -#include "Framework/StoneException.h" - -namespace OrthancStone -{ - ICommand* BaseCommandBuilder::CreateFromJson(const Json::Value& commandJson) - { - if (!commandJson.isObject() || !commandJson["command"].isString()) - { - throw StoneException(ErrorCode_CommandJsonInvalidFormat); - } - - if (commandJson["commandType"].isString() && commandJson["commandType"].asString() == "generic-no-arg-command") - { - return new GenericNoArgCommand(commandJson["command"].asString().c_str()); - } - else if (commandJson["commandType"].isString() && commandJson["commandType"].asString() == "generic-one-string-arg-command") - { - // TODO: we should create a command with a string arg ! - return new GenericNoArgCommand(commandJson["command"].asString().c_str()); - } - - return NULL; - } - -} diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Commands/BaseCommandBuilder.h --- a/Applications/Commands/BaseCommandBuilder.h Mon Mar 18 16:01:07 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 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 - -#include "ICommand.h" -#include "../../Applications/Commands/ICommandBuilder.h" - -// TODO: must be reworked completely (check trello) - -namespace OrthancStone -{ - class BaseCommandBuilder : public ICommandBuilder - { - public: - virtual ICommand* CreateFromJson(const Json::Value& commandJson); - }; -} diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Commands/ICommand.h --- a/Applications/Commands/ICommand.h Mon Mar 18 16:01:07 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 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 - -// TODO: must be reworked completely (check trello) - -namespace OrthancStone -{ - class ICommand // TODO noncopyable - { - protected: - std::string name_; - ICommand(const std::string& name) - : name_(name) - {} - public: - virtual ~ICommand() - {} - virtual void Execute() = 0; -// virtual void Configure(const Json::Value& arguments) = 0; - const std::string& GetName() const - { - return name_; - } - }; - - - template - class BaseCommand : public ICommand - { - protected: - BaseCommand(const std::string& name) - : ICommand(name) - {} - - public: - static ICommand* Create() { - return new TCommand(); - } - - virtual void Configure(const Json::Value& arguments) { - } - }; - - class NoopCommand : public BaseCommand - { - public: - NoopCommand() - : BaseCommand("noop") - {} - virtual void Execute() {} - }; - - class GenericNoArgCommand : public BaseCommand - { - public: - GenericNoArgCommand(const std::string& name) - : BaseCommand(name) - {} - virtual void Execute() {} // TODO currently not used but this is not nice at all ! - }; - - class GenericOneStringArgCommand : public BaseCommand - { - std::string argument_; - public: - GenericOneStringArgCommand(const std::string& name, const std::string& argument) - : BaseCommand(name) - {} - - const std::string& GetArgument() const {return argument_;} - virtual void Execute() {} // TODO currently not used but this is not nice at all ! - }; - -} diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Commands/ICommandBuilder.h --- a/Applications/Commands/ICommandBuilder.h Mon Mar 18 16:01:07 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 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 - -#include "ICommand.h" - -namespace OrthancStone -{ - - class ICommandBuilder : public boost::noncopyable - { - public: - virtual ICommand* CreateFromJson(const Json::Value& commandJson) = 0; - }; -} diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Commands/ICommandExecutor.h --- a/Applications/Commands/ICommandExecutor.h Mon Mar 18 16:01:07 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 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 - -namespace OrthancStone -{ - class ICommandExecutor : public boost::noncopyable - { - - }; -} diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/IStoneApplication.h --- a/Applications/IStoneApplication.h Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/IStoneApplication.h Tue Mar 19 14:43:46 2019 +0100 @@ -25,9 +25,6 @@ #include #include "../Framework/Viewport/WidgetViewport.h" #include "json/json.h" -#include "Commands/ICommand.h" -#include "Commands/BaseCommandBuilder.h" - namespace OrthancStone { @@ -52,6 +49,12 @@ virtual void Initialize(StoneApplicationContext* context, IStatusBar& statusBar, const boost::program_options::variables_map& parameters) = 0; + + /** + This method is meant to process messages received from the outside world (i.e. GUI) + */ + virtual void HandleSerializedMessage(const char* data) = 0; + #if ORTHANC_ENABLE_WASM==1 virtual void InitializeWasm() {} // specific initialization when the app is running in WebAssembly. This is called after the other Initialize() #endif @@ -61,16 +64,6 @@ virtual std::string GetTitle() const = 0; virtual IWidget* GetCentralWidget() = 0; - virtual void Finalize() = 0; - - virtual BaseCommandBuilder& GetCommandBuilder() = 0; - - virtual void HandleSerializedMessage(const char* data) {}; - - virtual void ExecuteCommand(ICommand& command) - { - } }; - } diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/CMakeLists.txt --- a/Applications/Samples/CMakeLists.txt Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/CMakeLists.txt Tue Mar 19 14:43:46 2019 +0100 @@ -8,6 +8,10 @@ include(../../Resources/CMake/OrthancStoneParameters.cmake) +if (OPENSSL_NO_CAPIENG) +add_definitions(-DOPENSSL_NO_CAPIENG=1) +endif() + #set(ENABLE_DCMTK ON) set(ENABLE_SDL OFF CACHE BOOL "Target SDL Native application") @@ -38,7 +42,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${WASM_FLAGS}") # not always clear which flags are for the compiler and which one are for the linker -> pass them all to the linker too - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Applications/Samples/samples-library.js") + # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Applications/Samples/samples-library.js") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmWebService.js") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmDelayedCallExecutor.js") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/default-library.js") @@ -181,16 +185,20 @@ list(APPEND SIMPLE_VIEWER_APPLICATION_SOURCES ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Wasm/mainWasm.cpp ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.cpp + ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.h ${STONE_WASM_SOURCES} ) endif() add_executable(OrthancStoneSimpleViewer - ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp - ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/ThumbnailInteractor.cpp + ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/AppStatus.h ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/MainWidgetInteractor.cpp - ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/AppStatus.h + ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/MainWidgetInteractor.h ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Messages.h + ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp + ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/SimpleViewerApplication.h + ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/ThumbnailInteractor.cpp + ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/ThumbnailInteractor.h ${SIMPLE_VIEWER_APPLICATION_SOURCES} ) target_link_libraries(OrthancStoneSimpleViewer OrthancStone) diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SampleApplicationBase.h --- a/Applications/Samples/SampleApplicationBase.h Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SampleApplicationBase.h Tue Mar 19 14:43:46 2019 +0100 @@ -41,30 +41,35 @@ class SampleApplicationBase : public IStoneApplication { protected: - BaseCommandBuilder commandBuilder_; - WorldSceneWidget* mainWidget_; // ownership is transfered to the application context + // ownership is transferred to the application context + WorldSceneWidget* mainWidget_; public: virtual void Initialize(StoneApplicationContext* context, IStatusBar& statusBar, - const boost::program_options::variables_map& parameters) + const boost::program_options::variables_map& parameters) ORTHANC_OVERRIDE { } - virtual std::string GetTitle() const + virtual std::string GetTitle() const ORTHANC_OVERRIDE { return "Stone of Orthanc - Sample"; } - virtual BaseCommandBuilder& GetCommandBuilder() {return commandBuilder_;} + /** + * In the basic samples, the commands are handled by the platform adapter and NOT + * by the application handler + */ + virtual void HandleSerializedMessage(const char* data) ORTHANC_OVERRIDE {}; - virtual void Finalize() {} - virtual IWidget* GetCentralWidget() {return mainWidget_;} + + virtual void Finalize() ORTHANC_OVERRIDE {} + virtual IWidget* GetCentralWidget() ORTHANC_OVERRIDE {return mainWidget_;} #if ORTHANC_ENABLE_WASM==1 // default implementations for a single canvas named "canvas" in the HTML and an emtpy WasmApplicationAdapter - virtual void InitializeWasm() + virtual void InitializeWasm() ORTHANC_OVERRIDE { AttachWidgetToWasmViewport("canvas", mainWidget_); } diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/Samples-status.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/Samples-status.md Tue Mar 19 14:43:46 2019 +0100 @@ -0,0 +1,103 @@ +Executable versions +================ +Generic options +---------------------- +``` +("help", "Display this help and exit") +("verbose", "Be verbose in logs") +("orthanc", boost::program_options::value() + ->default_value("http://localhost:8042/"), + "URL to the Orthanc server") +("username", "Username for the Orthanc server") +("password", "Password for the Orthanc server") +("https-verify", boost::program_options::value() + ->default_value(true), "Check HTTPS certificates") +``` +OrthancStoneSimpleViewer +------------------------------------- +- Options: + ``` + - "studyId", std::string, "Orthanc ID of the study" + ``` +- study loading works OK +- Invert does not work: +``` +void SimpleViewerApplication::ExecuteAction(SimpleViewerApplication::Actions action) + { + // TODO + } +``` + +OrthancStoneSimpleViewerSingleFile +------------------------------------- +- Options: + ``` + - "studyId", std::string, "Orthanc ID of the study" + ``` + +Study loading works. + +The `line` and `circle` buttons work and call this: +``` +virtual void OnTool1Clicked() +{ + currentTool_ = Tools_LineMeasure; +} + +virtual void OnTool2Clicked() +{ + currentTool_ = Tools_CircleMeasure; +} +``` +The `action1` and `action2` buttons are not connected + +The following is displayed in the console at launch time: +``` +W0313 12:20:12.790449 NativeStoneApplicationRunner.cpp:55] Use the key "s" to reinitialize the layout +W0313 12:20:12.790449 NativeStoneApplicationRunner.cpp:55] Use the key "n" to go to next image in the main viewport +``` +However, when looking at `MainWidgetInteractor::KeyPressed` (`SimpleViewerApplicationSingleFile.h:169`), only the following is processed: +- 's': reset layout +- 'l': select line tool +- 'c': select circle tool + +OrthancStoneSingleFrame +------------------------------------- +``` +generic.add_options() +("instance", boost::program_options::value(), +"Orthanc ID of the instance") +("frame", boost::program_options::value() + ->default_value(0), +"Number of the frame, for multi-frame DICOM instances") +("smooth", boost::program_options::value() + ->default_value(true), +"Enable bilinear interpolation to smooth the image"); +``` +only key handled in `KeyPressed` is `s` to call `widget.FitContent()` + + +OrthancStoneSingleFrameEditor +------------------------------------- +``` +generic.add_options() +("instance", boost::program_options::value(), +"Orthanc ID of the instance") +("frame", boost::program_options::value() + ->default_value(0), +"Number of the frame, for multi-frame DICOM instances"); +``` +Available commands in `KeyPressed` (`SingleFrameEditorApplication.h:280`): +- 'a' widget.FitContent() +- 'c' Crop tool +- 'm' Mask tool +- 'd' dump to json and diplay result (?) +- 'e' export current view to Dicom with dummy tags (?) +- 'i' wdiget.SwitchInvert +- 't' Move tool +- 'n' switch between nearest and bilinear interpolation +- 'r' Rotate tool +- 's' Resize tool +- 'w' Windowing tool +- 'ctrl+y' redo +- 'ctrl+z' undo diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SimpleViewer/MainWidgetInteractor.cpp --- a/Applications/Samples/SimpleViewer/MainWidgetInteractor.cpp Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SimpleViewer/MainWidgetInteractor.cpp Tue Mar 19 14:43:46 2019 +0100 @@ -37,33 +37,32 @@ { if (button == MouseButton_Left) { - if (application_.GetCurrentTool() == SimpleViewerApplication::Tools_LineMeasure) + if (application_.GetCurrentTool() == Tool_LineMeasure) { return new LineMeasureTracker(statusBar, dynamic_cast(widget).GetSlice(), x, y, 255, 0, 0, application_.GetFont()); } - else if (application_.GetCurrentTool() == SimpleViewerApplication::Tools_CircleMeasure) + else if (application_.GetCurrentTool() == Tool_CircleMeasure) { return new CircleMeasureTracker(statusBar, dynamic_cast(widget).GetSlice(), x, y, 255, 0, 0, application_.GetFont()); } - else if (application_.GetCurrentTool() == SimpleViewerApplication::Tools_Crop) + else if (application_.GetCurrentTool() == Tool_Crop) { // TODO } - else if (application_.GetCurrentTool() == SimpleViewerApplication::Tools_Windowing) + else if (application_.GetCurrentTool() == Tool_Windowing) { // TODO } - else if (application_.GetCurrentTool() == SimpleViewerApplication::Tools_Zoom) + else if (application_.GetCurrentTool() == Tool_Zoom) { // TODO } - else if (application_.GetCurrentTool() == SimpleViewerApplication::Tools_Pan) + else if (application_.GetCurrentTool() == Tool_Pan) { // TODO } - } return NULL; } diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SimpleViewer/Qt/SimpleViewerMainWindow.cpp --- a/Applications/Samples/SimpleViewer/Qt/SimpleViewerMainWindow.cpp Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SimpleViewer/Qt/SimpleViewerMainWindow.cpp Tue Mar 19 14:43:46 2019 +0100 @@ -27,8 +27,15 @@ #include #include "../SimpleViewerApplication.h" + namespace SimpleViewer { + template + bool ExecuteCommand(U* handler, const T& command) + { + std::string serializedCommand = StoneSerialize(command); + StoneDispatchToHandler(serializedCommand, handler); + } SimpleViewerMainWindow::SimpleViewerMainWindow( OrthancStone::NativeStoneApplicationContext& context, @@ -67,43 +74,36 @@ void SimpleViewerMainWindow::cropClicked() { - GenericNoArgCommand command("selectTool:crop"); - stoneApplication_.ExecuteCommand(command); + stoneApplication_.ExecuteCommand(SelectTool(Tool_Crop)); } void SimpleViewerMainWindow::undoCropClicked() { - GenericNoArgCommand command("action:undo-crop"); - stoneApplication_.ExecuteCommand(command); + stoneApplication_.ExecuteCommand(Action(ActionType_UndoCrop)); } void SimpleViewerMainWindow::lineClicked() { - GenericNoArgCommand command("selectTool:line-measure"); - stoneApplication_.ExecuteCommand(command); + stoneApplication_.ExecuteCommand(SelectTool(Tool_LineMeasure)); } void SimpleViewerMainWindow::circleClicked() { - GenericNoArgCommand command("selectTool:circle-measure"); - stoneApplication_.ExecuteCommand(command); + stoneApplication_.ExecuteCommand(SelectTool(Tool_CircleMeasure)); } void SimpleViewerMainWindow::windowingClicked() { - GenericNoArgCommand command("selectTool:windowing"); - stoneApplication_.ExecuteCommand(command); + stoneApplication_.ExecuteCommand(SelectTool(Tool_Windowing)); } void SimpleViewerMainWindow::rotateClicked() { - GenericNoArgCommand command("action:rotate"); - stoneApplication_.ExecuteCommand(command); + stoneApplication_.ExecuteCommand(Action(ActionType_Rotate)); } void SimpleViewerMainWindow::invertClicked() { - GenericNoArgCommand command("action:invert"); - stoneApplication_.ExecuteCommand(command); + stoneApplication_.ExecuteCommand(Action(ActionType_Invert)); } } diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp --- a/Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp Tue Mar 19 14:43:46 2019 +0100 @@ -153,13 +153,16 @@ void SimpleViewerApplication::LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId) { LOG(INFO) << "Loading thumbnail for series " << seriesId; + SliceViewerWidget* thumbnailWidget = new SliceViewerWidget(IObserver::GetBroker(), "thumbnail-series-" + seriesId); thumbnails_.push_back(thumbnailWidget); thumbnailsLayout_->AddWidget(thumbnailWidget); + thumbnailWidget->RegisterObserverCallback( new Callable (*this, &SimpleViewerApplication::OnWidgetGeometryChanged)); + smartLoader_->SetFrameInWidget(*thumbnailWidget, 0, instanceId, 0); thumbnailWidget->SetInteractor(*thumbnailInteractor_); } @@ -180,53 +183,29 @@ smartLoader_->SetFrameInWidget(*mainWidget_, 0, instancesIdsPerSeriesId_[seriesId][0], 0); } - - - void SimpleViewerApplication::ExecuteCommand(ICommand& command) + bool SimpleViewerApplication::Handle(const StoneSampleCommands::SelectTool& value) { - statusBar_->SetMessage("received command: " + std::string(command.GetName())); - if (command.GetName() == "selectTool:circle-measure") - { - SelectTool(Tools_CircleMeasure); - } - else if (command.GetName() == "selectTool:line-measure") - { - SelectTool(Tools_LineMeasure); - } - else if (command.GetName() == "selectTool:crop") - { - SelectTool(Tools_Crop); - } - else if (command.GetName() == "selectTool:windowing") - { - SelectTool(Tools_Windowing); - } - else if (command.GetName() == "action:rotate") - { - ExecuteAction(Actions_Rotate); - } - else if (command.GetName() == "action:undo-crop") - { - ExecuteAction(Actions_UndoCrop); - } - else if (command.GetName() == "action:invert") - { - ExecuteAction(Actions_Invert); - } - else - { - command.Execute(); - } + currentTool_ = value.tool; + return true; } - void SimpleViewerApplication::ExecuteAction(SimpleViewerApplication::Actions action) + bool SimpleViewerApplication::Handle(const StoneSampleCommands::Action& value) { - // TODO - } - - void SimpleViewerApplication::SelectTool(SimpleViewerApplication::Tools tool) - { - currentTool_ = tool; + switch (value.type) + { + case ActionType_Invert: + // TODO + break; + case ActionType_UndoCrop: + // TODO + break; + case ActionType_Rotate: + // TODO + break; + default: + throw std::runtime_error("Action type not supported"); + } + return true; } #if ORTHANC_ENABLE_QT==1 diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SimpleViewer/SimpleViewerApplication.h --- a/Applications/Samples/SimpleViewer/SimpleViewerApplication.h Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SimpleViewer/SimpleViewerApplication.h Tue Mar 19 14:43:46 2019 +0100 @@ -21,6 +21,12 @@ #pragma once + /* + This header contains the command definitions for the sample applications + */ +#include "Applications/Samples/StoneSampleCommands_generated.hpp" +using namespace StoneSampleCommands; + #include "Applications/IStoneApplication.h" #include "Framework/Layers/CircleMeasureTracker.h" @@ -53,10 +59,11 @@ namespace SimpleViewer { - class SimpleViewerApplication : - public IStoneApplication, - public IObserver, - public IObservable + class SimpleViewerApplication + : public IStoneApplication + , public IObserver + , public IObservable + , public StoneSampleCommands::IHandler { public: @@ -71,23 +78,9 @@ } }; - enum Tools { - Tools_LineMeasure, - Tools_CircleMeasure, - Tools_Crop, - Tools_Windowing, - Tools_Zoom, - Tools_Pan - }; + private: + Tool currentTool_; - enum Actions { - Actions_Rotate, - Actions_Invert, - Actions_UndoCrop - }; - - private: - Tools currentTool_; std::auto_ptr mainWidgetInteractor_; std::auto_ptr thumbnailInteractor_; LayoutWidget* mainLayout_; @@ -96,8 +89,6 @@ std::vector thumbnails_; std::map > instancesIdsPerSeriesId_; std::map seriesTags_; - BaseCommandBuilder commandBuilder_; - unsigned int currentInstanceIndex_; OrthancStone::WidgetViewport* wasmViewport1_; OrthancStone::WidgetViewport* wasmViewport2_; @@ -111,7 +102,7 @@ SimpleViewerApplication(MessageBroker& broker) : IObserver(broker), IObservable(broker), - currentTool_(Tools_LineMeasure), + currentTool_(StoneSampleCommands::Tool_LineMeasure), mainLayout_(NULL), currentInstanceIndex_(0), wasmViewport1_(NULL), @@ -120,13 +111,13 @@ font_.LoadFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16); } - virtual void Finalize() {} - virtual IWidget* GetCentralWidget() {return mainLayout_;} + virtual void Finalize() ORTHANC_OVERRIDE {} + virtual IWidget* GetCentralWidget() ORTHANC_OVERRIDE {return mainLayout_;} - virtual void DeclareStartupOptions(boost::program_options::options_description& options); + virtual void DeclareStartupOptions(boost::program_options::options_description& options) ORTHANC_OVERRIDE; virtual void Initialize(StoneApplicationContext* context, IStatusBar& statusBar, - const boost::program_options::variables_map& parameters); + const boost::program_options::variables_map& parameters) ORTHANC_OVERRIDE; void OnStudyListReceived(const OrthancApiClient::JsonResponseReadyMessage& message); @@ -142,9 +133,8 @@ void SelectSeriesInMainViewport(const std::string& seriesId); - void SelectTool(Tools tool); - - Tools GetCurrentTool() const + + Tool GetCurrentTool() const { return currentTool_; } @@ -154,15 +144,26 @@ return font_; } - void ExecuteAction(Actions action); + // ExecuteAction method was empty (its body was a single "TODO" comment) + virtual bool Handle(const SelectTool& value) ORTHANC_OVERRIDE; + virtual bool Handle(const Action& value) ORTHANC_OVERRIDE; - virtual std::string GetTitle() const {return "SimpleViewer";} - virtual void ExecuteCommand(ICommand& command); - virtual BaseCommandBuilder& GetCommandBuilder() {return commandBuilder_;} + template + bool ExecuteCommand(const T& cmd) + { + std::string cmdStr = StoneSampleCommands::StoneSerialize(cmd); + return StoneSampleCommands::StoneDispatchToHandler(cmdStr, this); + } + virtual void HandleSerializedMessage(const char* data) ORTHANC_OVERRIDE + { + StoneSampleCommands::StoneDispatchToHandler(data, this); + } + + virtual std::string GetTitle() const ORTHANC_OVERRIDE {return "SimpleViewer";} #if ORTHANC_ENABLE_WASM==1 - virtual void InitializeWasm(); + virtual void InitializeWasm() ORTHANC_OVERRIDE; #endif #if ORTHANC_ENABLE_QT==1 diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.cpp --- a/Applications/Samples/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.cpp Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.cpp Tue Mar 19 14:43:46 2019 +0100 @@ -45,7 +45,7 @@ writer->write(event, &outputStr); - NotifyStatusUpdateFromCppToWeb(outputStr.str()); + NotifyStatusUpdateFromCppToWebWithString(outputStr.str()); } } // namespace SimpleViewer \ No newline at end of file diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SimpleViewer/Wasm/simple-viewer.ts --- a/Applications/Samples/SimpleViewer/Wasm/simple-viewer.ts Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SimpleViewer/Wasm/simple-viewer.ts Tue Mar 19 14:43:46 2019 +0100 @@ -9,7 +9,7 @@ args: { } }; - wasmApplicationRunner.SendCommandToStoneApplication(JSON.stringify(command)); + wasmApplicationRunner.SendSerializedMessageToStoneApplication(JSON.stringify(command)); } function PerformAction(actionName: string) { @@ -19,7 +19,7 @@ args: { } }; - wasmApplicationRunner.SendCommandToStoneApplication(JSON.stringify(command)); + wasmApplicationRunner.SendSerializedMessageToStoneApplication(JSON.stringify(command)); } class SimpleViewerUI { diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SimpleViewerApplicationSingleFile.h --- a/Applications/Samples/SimpleViewerApplicationSingleFile.h Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SimpleViewerApplicationSingleFile.h Tue Mar 19 14:43:46 2019 +0100 @@ -127,12 +127,12 @@ { if (button == MouseButton_Left) { - if (application_.currentTool_ == Tools_LineMeasure) + if (application_.currentTool_ == Tool_LineMeasure) { return new LineMeasureTracker(statusBar, dynamic_cast(widget).GetSlice(), x, y, 255, 0, 0, application_.GetFont()); } - else if (application_.currentTool_ == Tools_CircleMeasure) + else if (application_.currentTool_ == Tool_CircleMeasure) { return new CircleMeasureTracker(statusBar, dynamic_cast(widget).GetSlice(), x, y, 255, 0, 0, application_.GetFont()); @@ -179,11 +179,11 @@ break; case 'l': - application_.currentTool_ = Tools_LineMeasure; + application_.currentTool_ = Tool_LineMeasure; break; case 'c': - application_.currentTool_ = Tools_CircleMeasure; + application_.currentTool_ = Tool_CircleMeasure; break; default: @@ -207,20 +207,15 @@ virtual void HandleSerializedMessageFromWeb(std::string& output, const std::string& input) { - // the simple viewer does not use the serialized messages facilities - } - - virtual void HandleCommandFromWeb(std::string& output, const std::string& input) - { if (input == "select-tool:line-measure") { - viewerApplication_.currentTool_ = Tools_LineMeasure; - NotifyStatusUpdateFromCppToWeb("currentTool=line-measure"); + viewerApplication_.currentTool_ = Tool_LineMeasure; + NotifyStatusUpdateFromCppToWebWithString("currentTool=line-measure"); } else if (input == "select-tool:circle-measure") { - viewerApplication_.currentTool_ = Tools_CircleMeasure; - NotifyStatusUpdateFromCppToWeb("currentTool=circle-measure"); + viewerApplication_.currentTool_ = Tool_CircleMeasure; + NotifyStatusUpdateFromCppToWebWithString("currentTool=circle-measure"); } output = "ok"; @@ -231,19 +226,19 @@ UpdateStoneApplicationStatusFromCppWithSerializedMessage(statusUpdateMessage.c_str()); } - virtual void NotifyStatusUpdateFromCppToWeb(const std::string& statusUpdateMessage) + virtual void NotifyStatusUpdateFromCppToWebWithString(const std::string& statusUpdateMessage) { UpdateStoneApplicationStatusFromCppWithString(statusUpdateMessage.c_str()); } }; #endif - enum Tools { - Tools_LineMeasure, - Tools_CircleMeasure + enum Tool { + Tool_LineMeasure, + Tool_CircleMeasure }; - Tools currentTool_; + Tool currentTool_; std::auto_ptr mainWidgetInteractor_; std::auto_ptr thumbnailInteractor_; LayoutWidget* mainLayout_; @@ -265,7 +260,7 @@ public: SimpleViewerApplication(MessageBroker& broker) : IObserver(broker), - currentTool_(Tools_LineMeasure), + currentTool_(Tool_LineMeasure), mainLayout_(NULL), currentInstanceIndex_(0), wasmViewport1_(NULL), @@ -438,8 +433,8 @@ virtual void OnPushButton1Clicked() {} virtual void OnPushButton2Clicked() {} - virtual void OnTool1Clicked() { currentTool_ = Tools_LineMeasure;} - virtual void OnTool2Clicked() { currentTool_ = Tools_CircleMeasure;} + virtual void OnTool1Clicked() { currentTool_ = Tool_LineMeasure;} + virtual void OnTool2Clicked() { currentTool_ = Tool_CircleMeasure;} virtual void GetButtonNames(std::string& pushButton1, std::string& pushButton2, diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SingleFrameApplication.h --- a/Applications/Samples/SingleFrameApplication.h Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SingleFrameApplication.h Tue Mar 19 14:43:46 2019 +0100 @@ -138,7 +138,7 @@ if (slice >= static_cast(source_->GetSliceCount())) { - slice = source_->GetSliceCount() - 1; + slice = static_cast(source_->GetSliceCount()) - 1; } if (slice != static_cast(slice_)) @@ -160,7 +160,7 @@ if (source_ != NULL && index < source_->GetSliceCount()) { - slice_ = index; + slice_ = static_cast(index); #if 1 GetMainWidget().SetSlice(source_->GetSlice(slice_).GetGeometry()); diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/SingleFrameEditorApplication.h --- a/Applications/Samples/SingleFrameEditorApplication.h Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/SingleFrameEditorApplication.h Tue Mar 19 14:43:46 2019 +0100 @@ -490,8 +490,10 @@ fontRegistry_.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16); scene_.reset(new RadiographyScene(GetBroker())); + + RadiographyLayer& dicomLayer = scene_->LoadDicomFrame(context->GetOrthancApiClient(), instance, 0, false, NULL); //scene_->LoadDicomFrame(instance, frame, false); //.SetPan(200, 0); - RadiographyLayer& dicomLayer = scene_->LoadDicomFrame(context->GetOrthancApiClient(), "61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", 0, false, NULL); + // = scene_->LoadDicomFrame(context->GetOrthancApiClient(), "61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", 0, false, NULL); #if !defined(ORTHANC_ENABLE_WASM) || ORTHANC_ENABLE_WASM != 1 Orthanc::HttpClient::ConfigureSsl(true, "/etc/ssl/certs/ca-certificates.crt"); diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/StoneSampleCommands.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/StoneSampleCommands.yml Tue Mar 19 14:43:46 2019 +0100 @@ -0,0 +1,35 @@ +# +# 1 2 3 4 5 6 7 8 +# 345678901234567890123456789012345678901234567890123456789012345678901234567890 +# +rootName: StoneSampleCommands + +# +---------------------------------+ +# | Messages from TypeScript to C++ | +# +---------------------------------+ + +enum Tool: + - LineMeasure + - CircleMeasure + - Crop + - Windowing + - Zoom + - Pan + - Move + - Rotate + - Resize + - Mask + +struct SelectTool: + __handler: cpp + tool: Tool + +enum ActionType: + - UndoCrop + - Rotate + - Invert + +struct Action: + __handler: cpp + type: ActionType + diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/StoneSampleCommands_generate.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/StoneSampleCommands_generate.py Tue Mar 19 14:43:46 2019 +0100 @@ -0,0 +1,16 @@ +import sys +import os + +# add the generation script location to the search paths +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'Resources', 'CodeGeneration')) + +# import the code generation tooling script +import stonegentool + +schemaFile = os.path.join(os.path.dirname(__file__), 'StoneSampleCommands.yml') +outDir = os.path.dirname(__file__) + +# ignition! +stonegentool.Process(schemaFile, outDir) + + diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/StoneSampleCommands_generated.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/StoneSampleCommands_generated.hpp Tue Mar 19 14:43:46 2019 +0100 @@ -0,0 +1,703 @@ +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 + +Generated on 2019-03-18 12:07:42.696093 by stonegentool + +*/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +//#define STONEGEN_NO_CPP11 1 + +#ifdef STONEGEN_NO_CPP11 +#define StoneSmartPtr std::auto_ptr +#else +#define StoneSmartPtr std::unique_ptr +#endif + +namespace StoneSampleCommands +{ + /** Throws in case of problem */ + inline void _StoneDeserializeValue(int32_t& destValue, const Json::Value& jsonValue) + { + destValue = jsonValue.asInt(); + } + + inline Json::Value _StoneSerializeValue(int32_t value) + { + Json::Value result(value); + return result; + } + + inline void _StoneDeserializeValue(Json::Value& destValue, const Json::Value& jsonValue) + { + destValue = jsonValue; + } + + inline Json::Value _StoneSerializeValue(Json::Value value) + { + return value; + } + + /** Throws in case of problem */ + inline void _StoneDeserializeValue(double& destValue, const Json::Value& jsonValue) + { + destValue = jsonValue.asDouble(); + } + + inline Json::Value _StoneSerializeValue(double value) + { + Json::Value result(value); + return result; + } + + /** Throws in case of problem */ + inline void _StoneDeserializeValue(bool& destValue, const Json::Value& jsonValue) + { + destValue = jsonValue.asBool(); + } + + inline Json::Value _StoneSerializeValue(bool value) + { + Json::Value result(value); + return result; + } + + /** Throws in case of problem */ + inline void _StoneDeserializeValue( + std::string& destValue + , const Json::Value& jsonValue) + { + destValue = jsonValue.asString(); + } + + inline Json::Value _StoneSerializeValue(const std::string& value) + { + // the following is better than + Json::Value result(value.data(),value.data()+value.size()); + return result; + } + + inline std::string MakeIndent(size_t indent) + { + char* txt = reinterpret_cast(malloc(indent+1)); // NO EXCEPTION BELOW!!!!!!!!!!!! + for(size_t i = 0; i < indent; ++i) + txt[i] = ' '; + txt[indent] = 0; + std::string retVal(txt); + free(txt); // NO EXCEPTION ABOVE !!!!!!!!!! + return retVal; + } + + // generic dumper + template + std::ostream& StoneDumpValue(std::ostream& out, const T& value, size_t indent) + { + out << MakeIndent(indent) << value; + return out; + } + + // string dumper + inline std::ostream& StoneDumpValue(std::ostream& out, const std::string& value, size_t indent) + { + out << MakeIndent(indent) << "\"" << value << "\""; + return out; + } + + /** Throws in case of problem */ + template + void _StoneDeserializeValue( + std::map& destValue, const Json::Value& jsonValue) + { + destValue.clear(); + for ( + Json::Value::const_iterator itr = jsonValue.begin(); + itr != jsonValue.end(); + itr++) + { + std::string key; + _StoneDeserializeValue(key, itr.key()); + + T innerDestValue; + _StoneDeserializeValue(innerDestValue, *itr); + + destValue[key] = innerDestValue; + } + } + + template + Json::Value _StoneSerializeValue(const std::map& value) + { + Json::Value result(Json::objectValue); + + for (typename std::map::const_iterator it = value.cbegin(); + it != value.cend(); ++it) + { + // it->first it->second + result[it->first] = _StoneSerializeValue(it->second); + } + return result; + } + + template + std::ostream& StoneDumpValue(std::ostream& out, const std::map& value, size_t indent) + { + out << MakeIndent(indent) << "{\n"; + for (typename std::map::const_iterator it = value.cbegin(); + it != value.cend(); ++it) + { + out << MakeIndent(indent+2) << "\"" << it->first << "\" : "; + StoneDumpValue(out, it->second, indent+2); + } + out << MakeIndent(indent) << "}\n"; + return out; + } + + /** Throws in case of problem */ + template + void _StoneDeserializeValue( + std::vector& destValue, const Json::Value& jsonValue) + { + destValue.clear(); + destValue.reserve(jsonValue.size()); + for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++) + { + T innerDestValue; + _StoneDeserializeValue(innerDestValue, jsonValue[i]); + destValue.push_back(innerDestValue); + } + } + + template + Json::Value _StoneSerializeValue(const std::vector& value) + { + Json::Value result(Json::arrayValue); + for (size_t i = 0; i < value.size(); ++i) + { + result.append(_StoneSerializeValue(value[i])); + } + return result; + } + + template + std::ostream& StoneDumpValue(std::ostream& out, const std::vector& value, size_t indent) + { + out << MakeIndent(indent) << "[\n"; + for (size_t i = 0; i < value.size(); ++i) + { + StoneDumpValue(out, value[i], indent+2); + } + out << MakeIndent(indent) << "]\n"; + return out; + } + + inline void StoneCheckSerializedValueTypeGeneric(const Json::Value& value) + { + if ((!value.isMember("type")) || (!value["type"].isString())) + { + std::stringstream ss; + ss << "Cannot deserialize value ('type' key invalid)"; + throw std::runtime_error(ss.str()); + } + } + + inline void StoneCheckSerializedValueType( + const Json::Value& value, std::string typeStr) + { + StoneCheckSerializedValueTypeGeneric(value); + + std::string actTypeStr = value["type"].asString(); + if (actTypeStr != typeStr) + { + std::stringstream ss; + ss << "Cannot deserialize type" << actTypeStr + << "into " << typeStr; + throw std::runtime_error(ss.str()); + } + } + + // end of generic methods + +// end of generic methods + + enum Tool { + Tool_LineMeasure, + Tool_CircleMeasure, + Tool_Crop, + Tool_Windowing, + Tool_Zoom, + Tool_Pan, + Tool_Move, + Tool_Rotate, + Tool_Resize, + Tool_Mask, + }; + + inline std::string ToString(const Tool& value) + { + if( value == Tool_LineMeasure) + { + return std::string("LineMeasure"); + } + if( value == Tool_CircleMeasure) + { + return std::string("CircleMeasure"); + } + if( value == Tool_Crop) + { + return std::string("Crop"); + } + if( value == Tool_Windowing) + { + return std::string("Windowing"); + } + if( value == Tool_Zoom) + { + return std::string("Zoom"); + } + if( value == Tool_Pan) + { + return std::string("Pan"); + } + if( value == Tool_Move) + { + return std::string("Move"); + } + if( value == Tool_Rotate) + { + return std::string("Rotate"); + } + if( value == Tool_Resize) + { + return std::string("Resize"); + } + if( value == Tool_Mask) + { + return std::string("Mask"); + } + std::stringstream ss; + ss << "Value \"" << value << "\" cannot be converted to Tool. Possible values are: " + << " LineMeasure = " << static_cast(Tool_LineMeasure) << ", " + << " CircleMeasure = " << static_cast(Tool_CircleMeasure) << ", " + << " Crop = " << static_cast(Tool_Crop) << ", " + << " Windowing = " << static_cast(Tool_Windowing) << ", " + << " Zoom = " << static_cast(Tool_Zoom) << ", " + << " Pan = " << static_cast(Tool_Pan) << ", " + << " Move = " << static_cast(Tool_Move) << ", " + << " Rotate = " << static_cast(Tool_Rotate) << ", " + << " Resize = " << static_cast(Tool_Resize) << ", " + << " Mask = " << static_cast(Tool_Mask) << ", " + << std::endl; + std::string msg = ss.str(); + throw std::runtime_error(msg); + } + + inline void FromString(Tool& value, std::string strValue) + { + if( strValue == std::string("LineMeasure") ) + { + value = Tool_LineMeasure; + return; + } + if( strValue == std::string("CircleMeasure") ) + { + value = Tool_CircleMeasure; + return; + } + if( strValue == std::string("Crop") ) + { + value = Tool_Crop; + return; + } + if( strValue == std::string("Windowing") ) + { + value = Tool_Windowing; + return; + } + if( strValue == std::string("Zoom") ) + { + value = Tool_Zoom; + return; + } + if( strValue == std::string("Pan") ) + { + value = Tool_Pan; + return; + } + if( strValue == std::string("Move") ) + { + value = Tool_Move; + return; + } + if( strValue == std::string("Rotate") ) + { + value = Tool_Rotate; + return; + } + if( strValue == std::string("Resize") ) + { + value = Tool_Resize; + return; + } + if( strValue == std::string("Mask") ) + { + value = Tool_Mask; + return; + } + + std::stringstream ss; + ss << "String \"" << strValue << "\" cannot be converted to Tool. Possible values are: LineMeasure CircleMeasure Crop Windowing Zoom Pan Move Rotate Resize Mask "; + std::string msg = ss.str(); + throw std::runtime_error(msg); + } + + + inline void _StoneDeserializeValue( + Tool& destValue, const Json::Value& jsonValue) + { + FromString(destValue, jsonValue.asString()); + } + + inline Json::Value _StoneSerializeValue(const Tool& value) + { + std::string strValue = ToString(value); + return Json::Value(strValue); + } + + inline std::ostream& StoneDumpValue(std::ostream& out, const Tool& value, size_t indent = 0) + { + if( value == Tool_LineMeasure) + { + out << MakeIndent(indent) << "LineMeasure" << std::endl; + } + if( value == Tool_CircleMeasure) + { + out << MakeIndent(indent) << "CircleMeasure" << std::endl; + } + if( value == Tool_Crop) + { + out << MakeIndent(indent) << "Crop" << std::endl; + } + if( value == Tool_Windowing) + { + out << MakeIndent(indent) << "Windowing" << std::endl; + } + if( value == Tool_Zoom) + { + out << MakeIndent(indent) << "Zoom" << std::endl; + } + if( value == Tool_Pan) + { + out << MakeIndent(indent) << "Pan" << std::endl; + } + if( value == Tool_Move) + { + out << MakeIndent(indent) << "Move" << std::endl; + } + if( value == Tool_Rotate) + { + out << MakeIndent(indent) << "Rotate" << std::endl; + } + if( value == Tool_Resize) + { + out << MakeIndent(indent) << "Resize" << std::endl; + } + if( value == Tool_Mask) + { + out << MakeIndent(indent) << "Mask" << std::endl; + } + return out; + } + + + enum ActionType { + ActionType_UndoCrop, + ActionType_Rotate, + ActionType_Invert, + }; + + inline std::string ToString(const ActionType& value) + { + if( value == ActionType_UndoCrop) + { + return std::string("UndoCrop"); + } + if( value == ActionType_Rotate) + { + return std::string("Rotate"); + } + if( value == ActionType_Invert) + { + return std::string("Invert"); + } + std::stringstream ss; + ss << "Value \"" << value << "\" cannot be converted to ActionType. Possible values are: " + << " UndoCrop = " << static_cast(ActionType_UndoCrop) << ", " + << " Rotate = " << static_cast(ActionType_Rotate) << ", " + << " Invert = " << static_cast(ActionType_Invert) << ", " + << std::endl; + std::string msg = ss.str(); + throw std::runtime_error(msg); + } + + inline void FromString(ActionType& value, std::string strValue) + { + if( strValue == std::string("UndoCrop") ) + { + value = ActionType_UndoCrop; + return; + } + if( strValue == std::string("Rotate") ) + { + value = ActionType_Rotate; + return; + } + if( strValue == std::string("Invert") ) + { + value = ActionType_Invert; + return; + } + + std::stringstream ss; + ss << "String \"" << strValue << "\" cannot be converted to ActionType. Possible values are: UndoCrop Rotate Invert "; + std::string msg = ss.str(); + throw std::runtime_error(msg); + } + + + inline void _StoneDeserializeValue( + ActionType& destValue, const Json::Value& jsonValue) + { + FromString(destValue, jsonValue.asString()); + } + + inline Json::Value _StoneSerializeValue(const ActionType& value) + { + std::string strValue = ToString(value); + return Json::Value(strValue); + } + + inline std::ostream& StoneDumpValue(std::ostream& out, const ActionType& value, size_t indent = 0) + { + if( value == ActionType_UndoCrop) + { + out << MakeIndent(indent) << "UndoCrop" << std::endl; + } + if( value == ActionType_Rotate) + { + out << MakeIndent(indent) << "Rotate" << std::endl; + } + if( value == ActionType_Invert) + { + out << MakeIndent(indent) << "Invert" << std::endl; + } + return out; + } + + + +#ifdef _MSC_VER +#pragma region SelectTool +#endif //_MSC_VER + + struct SelectTool + { + Tool tool; + + SelectTool(Tool tool = Tool()) + { + this->tool = tool; + } + }; + + inline void _StoneDeserializeValue(SelectTool& destValue, const Json::Value& value) + { + _StoneDeserializeValue(destValue.tool, value["tool"]); + } + + inline Json::Value _StoneSerializeValue(const SelectTool& value) + { + Json::Value result(Json::objectValue); + result["tool"] = _StoneSerializeValue(value.tool); + + return result; + } + + inline std::ostream& StoneDumpValue(std::ostream& out, const SelectTool& value, size_t indent = 0) + { + out << MakeIndent(indent) << "{\n"; + out << MakeIndent(indent) << "tool:\n"; + StoneDumpValue(out, value.tool,indent+2); + out << "\n"; + + out << MakeIndent(indent) << "}\n"; + return out; + } + + inline void StoneDeserialize(SelectTool& destValue, const Json::Value& value) + { + StoneCheckSerializedValueType(value, "StoneSampleCommands.SelectTool"); + _StoneDeserializeValue(destValue, value["value"]); + } + + inline Json::Value StoneSerializeToJson(const SelectTool& value) + { + Json::Value result(Json::objectValue); + result["type"] = "StoneSampleCommands.SelectTool"; + result["value"] = _StoneSerializeValue(value); + return result; + } + + inline std::string StoneSerialize(const SelectTool& value) + { + Json::Value resultJson = StoneSerializeToJson(value); + std::string resultStr = resultJson.toStyledString(); + return resultStr; + } + +#ifdef _MSC_VER +#pragma endregion SelectTool +#endif //_MSC_VER + +#ifdef _MSC_VER +#pragma region Action +#endif //_MSC_VER + + struct Action + { + ActionType type; + + Action(ActionType type = ActionType()) + { + this->type = type; + } + }; + + inline void _StoneDeserializeValue(Action& destValue, const Json::Value& value) + { + _StoneDeserializeValue(destValue.type, value["type"]); + } + + inline Json::Value _StoneSerializeValue(const Action& value) + { + Json::Value result(Json::objectValue); + result["type"] = _StoneSerializeValue(value.type); + + return result; + } + + inline std::ostream& StoneDumpValue(std::ostream& out, const Action& value, size_t indent = 0) + { + out << MakeIndent(indent) << "{\n"; + out << MakeIndent(indent) << "type:\n"; + StoneDumpValue(out, value.type,indent+2); + out << "\n"; + + out << MakeIndent(indent) << "}\n"; + return out; + } + + inline void StoneDeserialize(Action& destValue, const Json::Value& value) + { + StoneCheckSerializedValueType(value, "StoneSampleCommands.Action"); + _StoneDeserializeValue(destValue, value["value"]); + } + + inline Json::Value StoneSerializeToJson(const Action& value) + { + Json::Value result(Json::objectValue); + result["type"] = "StoneSampleCommands.Action"; + result["value"] = _StoneSerializeValue(value); + return result; + } + + inline std::string StoneSerialize(const Action& value) + { + Json::Value resultJson = StoneSerializeToJson(value); + std::string resultStr = resultJson.toStyledString(); + return resultStr; + } + +#ifdef _MSC_VER +#pragma endregion Action +#endif //_MSC_VER + +#ifdef _MSC_VER +#pragma region Dispatching code +#endif //_MSC_VER + + class IHandler + { + public: + virtual bool Handle(const SelectTool& value) = 0; + virtual bool Handle(const Action& value) = 0; + }; + + /** Service function for StoneDispatchToHandler */ + inline bool StoneDispatchJsonToHandler( + const Json::Value& jsonValue, IHandler* handler) + { + StoneCheckSerializedValueTypeGeneric(jsonValue); + std::string type = jsonValue["type"].asString(); + if (type == "") + { + // this should never ever happen + throw std::runtime_error("Caught empty type while dispatching"); + } + else if (type == "StoneSampleCommands.SelectTool") + { + SelectTool value; + _StoneDeserializeValue(value, jsonValue["value"]); + return handler->Handle(value); + } + else if (type == "StoneSampleCommands.Action") + { + Action value; + _StoneDeserializeValue(value, jsonValue["value"]); + return handler->Handle(value); + } + else + { + return false; + } + } + + /** Takes a serialized type and passes this to the handler */ + inline bool StoneDispatchToHandler(std::string strValue, IHandler* handler) + { + Json::Value readValue; + + Json::CharReaderBuilder builder; + Json::CharReader* reader = builder.newCharReader(); + + StoneSmartPtr ptr(reader); + + std::string errors; + + bool ok = reader->parse( + strValue.c_str(), + strValue.c_str() + strValue.size(), + &readValue, + &errors + ); + if (!ok) + { + std::stringstream ss; + ss << "Jsoncpp parsing error: " << errors; + throw std::runtime_error(ss.str()); + } + return StoneDispatchJsonToHandler(readValue, handler); + } + +#ifdef _MSC_VER +#pragma endregion Dispatching code +#endif //_MSC_VER +} \ No newline at end of file diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/StoneSampleCommands_generated.ts --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/StoneSampleCommands_generated.ts Tue Mar 19 14:43:46 2019 +0100 @@ -0,0 +1,333 @@ +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 + +Generated on 2019-03-18 12:07:42.696093 by stonegentool + +*/ + +function StoneCheckSerializedValueType(value: any, typeStr: string) +{ + StoneCheckSerializedValueTypeGeneric(value); + + if (value['type'] != typeStr) + { + throw new Error( + `Cannot deserialize type ${value['type']} into ${typeStr}`); + } +} + +function isString(val: any) :boolean +{ + return ((typeof val === 'string') || (val instanceof String)); +} + +function StoneCheckSerializedValueTypeGeneric(value: any) +{ + // console.//log("+-------------------------------------------------+"); + // console.//log("| StoneCheckSerializedValueTypeGeneric |"); + // console.//log("+-------------------------------------------------+"); + // console.//log("value = "); + // console.//log(value); + if ( (!('type' in value)) || (!isString(value.type)) ) + { + throw new Error( + "Cannot deserialize value ('type' key invalid)"); + } +} + +// end of generic methods + +export enum Tool { + LineMeasure = "LineMeasure", + CircleMeasure = "CircleMeasure", + Crop = "Crop", + Windowing = "Windowing", + Zoom = "Zoom", + Pan = "Pan", + Move = "Move", + Rotate = "Rotate", + Resize = "Resize", + Mask = "Mask" +}; + +export function Tool_FromString(strValue:string) : Tool +{ + if( strValue == "LineMeasure" ) + { + return Tool.LineMeasure; + } + if( strValue == "CircleMeasure" ) + { + return Tool.CircleMeasure; + } + if( strValue == "Crop" ) + { + return Tool.Crop; + } + if( strValue == "Windowing" ) + { + return Tool.Windowing; + } + if( strValue == "Zoom" ) + { + return Tool.Zoom; + } + if( strValue == "Pan" ) + { + return Tool.Pan; + } + if( strValue == "Move" ) + { + return Tool.Move; + } + if( strValue == "Rotate" ) + { + return Tool.Rotate; + } + if( strValue == "Resize" ) + { + return Tool.Resize; + } + if( strValue == "Mask" ) + { + return Tool.Mask; + } + + let msg : string = `String ${strValue} cannot be converted to Tool. Possible values are: LineMeasure, CircleMeasure, Crop, Windowing, Zoom, Pan, Move, Rotate, Resize, Mask`; + throw new Error(msg); +} + +export function Tool_ToString(value:Tool) : string +{ + if( value == Tool.LineMeasure ) + { + return "LineMeasure"; + } + if( value == Tool.CircleMeasure ) + { + return "CircleMeasure"; + } + if( value == Tool.Crop ) + { + return "Crop"; + } + if( value == Tool.Windowing ) + { + return "Windowing"; + } + if( value == Tool.Zoom ) + { + return "Zoom"; + } + if( value == Tool.Pan ) + { + return "Pan"; + } + if( value == Tool.Move ) + { + return "Move"; + } + if( value == Tool.Rotate ) + { + return "Rotate"; + } + if( value == Tool.Resize ) + { + return "Resize"; + } + if( value == Tool.Mask ) + { + return "Mask"; + } + + let msg : string = `Value ${value} cannot be converted to Tool. Possible values are: `; + { + let _LineMeasure_enumValue : string = Tool.LineMeasure; // enums are strings in stonecodegen, so this will work. + let msg_LineMeasure : string = `LineMeasure (${_LineMeasure_enumValue}), `; + msg = msg + msg_LineMeasure; + } + { + let _CircleMeasure_enumValue : string = Tool.CircleMeasure; // enums are strings in stonecodegen, so this will work. + let msg_CircleMeasure : string = `CircleMeasure (${_CircleMeasure_enumValue}), `; + msg = msg + msg_CircleMeasure; + } + { + let _Crop_enumValue : string = Tool.Crop; // enums are strings in stonecodegen, so this will work. + let msg_Crop : string = `Crop (${_Crop_enumValue}), `; + msg = msg + msg_Crop; + } + { + let _Windowing_enumValue : string = Tool.Windowing; // enums are strings in stonecodegen, so this will work. + let msg_Windowing : string = `Windowing (${_Windowing_enumValue}), `; + msg = msg + msg_Windowing; + } + { + let _Zoom_enumValue : string = Tool.Zoom; // enums are strings in stonecodegen, so this will work. + let msg_Zoom : string = `Zoom (${_Zoom_enumValue}), `; + msg = msg + msg_Zoom; + } + { + let _Pan_enumValue : string = Tool.Pan; // enums are strings in stonecodegen, so this will work. + let msg_Pan : string = `Pan (${_Pan_enumValue}), `; + msg = msg + msg_Pan; + } + { + let _Move_enumValue : string = Tool.Move; // enums are strings in stonecodegen, so this will work. + let msg_Move : string = `Move (${_Move_enumValue}), `; + msg = msg + msg_Move; + } + { + let _Rotate_enumValue : string = Tool.Rotate; // enums are strings in stonecodegen, so this will work. + let msg_Rotate : string = `Rotate (${_Rotate_enumValue}), `; + msg = msg + msg_Rotate; + } + { + let _Resize_enumValue : string = Tool.Resize; // enums are strings in stonecodegen, so this will work. + let msg_Resize : string = `Resize (${_Resize_enumValue}), `; + msg = msg + msg_Resize; + } + { + let _Mask_enumValue : string = Tool.Mask; // enums are strings in stonecodegen, so this will work. + let msg_Mask : string = `Mask (${_Mask_enumValue})`; + msg = msg + msg_Mask; + } + throw new Error(msg); +} + +export enum ActionType { + UndoCrop = "UndoCrop", + Rotate = "Rotate", + Invert = "Invert" +}; + +export function ActionType_FromString(strValue:string) : ActionType +{ + if( strValue == "UndoCrop" ) + { + return ActionType.UndoCrop; + } + if( strValue == "Rotate" ) + { + return ActionType.Rotate; + } + if( strValue == "Invert" ) + { + return ActionType.Invert; + } + + let msg : string = `String ${strValue} cannot be converted to ActionType. Possible values are: UndoCrop, Rotate, Invert`; + throw new Error(msg); +} + +export function ActionType_ToString(value:ActionType) : string +{ + if( value == ActionType.UndoCrop ) + { + return "UndoCrop"; + } + if( value == ActionType.Rotate ) + { + return "Rotate"; + } + if( value == ActionType.Invert ) + { + return "Invert"; + } + + let msg : string = `Value ${value} cannot be converted to ActionType. Possible values are: `; + { + let _UndoCrop_enumValue : string = ActionType.UndoCrop; // enums are strings in stonecodegen, so this will work. + let msg_UndoCrop : string = `UndoCrop (${_UndoCrop_enumValue}), `; + msg = msg + msg_UndoCrop; + } + { + let _Rotate_enumValue : string = ActionType.Rotate; // enums are strings in stonecodegen, so this will work. + let msg_Rotate : string = `Rotate (${_Rotate_enumValue}), `; + msg = msg + msg_Rotate; + } + { + let _Invert_enumValue : string = ActionType.Invert; // enums are strings in stonecodegen, so this will work. + let msg_Invert : string = `Invert (${_Invert_enumValue})`; + msg = msg + msg_Invert; + } + throw new Error(msg); +} + + + +export class SelectTool { + tool:Tool; + + constructor() { + } + + public StoneSerialize(): string { + let container: object = {}; + container['type'] = 'StoneSampleCommands.SelectTool'; + container['value'] = this; + return JSON.stringify(container); + } + + public static StoneDeserialize(valueStr: string) : SelectTool + { + let value: any = JSON.parse(valueStr); + StoneCheckSerializedValueType(value, 'StoneSampleCommands.SelectTool'); + let result: SelectTool = value['value'] as SelectTool; + return result; + } +} +export class Action { + type:ActionType; + + constructor() { + } + + public StoneSerialize(): string { + let container: object = {}; + container['type'] = 'StoneSampleCommands.Action'; + container['value'] = this; + return JSON.stringify(container); + } + + public static StoneDeserialize(valueStr: string) : Action + { + let value: any = JSON.parse(valueStr); + StoneCheckSerializedValueType(value, 'StoneSampleCommands.Action'); + let result: Action = value['value'] as Action; + return result; + } +} + +export interface IHandler { +}; + +/** Service function for StoneDispatchToHandler */ +export function StoneDispatchJsonToHandler( + jsonValue: any, handler: IHandler): boolean +{ + StoneCheckSerializedValueTypeGeneric(jsonValue); + let type: string = jsonValue["type"]; + if (type == "") + { + // this should never ever happen + throw new Error("Caught empty type while dispatching"); + } + else + { + return false; + } +} + +/** Takes a serialized type and passes this to the handler */ +export function StoneDispatchToHandler( + strValue: string, handler: IHandler): boolean +{ + // console.//log("+------------------------------------------------+"); + // console.//log("| StoneDispatchToHandler |"); + // console.//log("+------------------------------------------------+"); + // console.//log("strValue = "); + // console.//log(strValue); + let jsonValue: any = JSON.parse(strValue) + return StoneDispatchJsonToHandler(jsonValue, handler); +} \ No newline at end of file diff -r 1c5104a6f7e4 -r d785ee57bd95 Applications/Samples/Web/simple-viewer-single-file.ts --- a/Applications/Samples/Web/simple-viewer-single-file.ts Mon Mar 18 16:01:07 2019 +0100 +++ b/Applications/Samples/Web/simple-viewer-single-file.ts Tue Mar 19 14:43:46 2019 +0100 @@ -9,7 +9,7 @@ toolName: toolName } }; - wasmApplicationRunner.SendCommandToStoneApplication(JSON.stringify(command)); + wasmApplicationRunner.SendSerializedMessageToStoneApplication(JSON.stringify(command)); } @@ -19,7 +19,7 @@ commandType: "simple", args: {} }; - wasmApplicationRunner.SendCommandToStoneApplication(JSON.stringify(command)); + wasmApplicationRunner.SendSerializedMessageToStoneApplication(JSON.stringify(command)); } //initializes the buttons diff -r 1c5104a6f7e4 -r d785ee57bd95 Framework/Widgets/LayoutWidget.cpp --- a/Framework/Widgets/LayoutWidget.cpp Mon Mar 18 16:01:07 2019 +0100 +++ b/Framework/Widgets/LayoutWidget.cpp Tue Mar 19 14:43:46 2019 +0100 @@ -74,7 +74,7 @@ std::vector relativeTouches; for (size_t t = 0; t < displayTouches.size(); t++) { - relativeTouches.push_back(Touch((int)displayTouches[t].x - left_, (int)displayTouches[t].y - top_)); + relativeTouches.push_back(Touch(displayTouches[t].x - left_, displayTouches[t].y - top_)); } tracker_->MouseMove(x - left_, y - top_, relativeTouches); @@ -226,7 +226,7 @@ } else if (isHorizontal_) { - unsigned int padding = paddingLeft_ + paddingRight_ + (children_.size() - 1) * paddingInternal_; + unsigned int padding = paddingLeft_ + paddingRight_ + (static_cast(children_.size()) - 1) * paddingInternal_; float childWidth = ((static_cast(width_) - static_cast(padding)) / static_cast(children_.size())); @@ -250,7 +250,7 @@ } else { - unsigned int padding = paddingTop_ + paddingBottom_ + (children_.size() - 1) * paddingInternal_; + unsigned int padding = paddingTop_ + paddingBottom_ + (static_cast(children_.size()) - 1) * paddingInternal_; float childHeight = ((static_cast(height_) - static_cast(padding)) / static_cast(children_.size())); diff -r 1c5104a6f7e4 -r d785ee57bd95 Platforms/Wasm/Defaults.cpp --- a/Platforms/Wasm/Defaults.cpp Mon Mar 18 16:01:07 2019 +0100 +++ b/Platforms/Wasm/Defaults.cpp Tue Mar 19 14:43:46 2019 +0100 @@ -357,21 +357,6 @@ return NULL; } - const char* EMSCRIPTEN_KEEPALIVE SendCommandToStoneApplication(const char* message) - { - static std::string output; // we don't want the string to be deallocated when we return to JS code so we always use the same string (this is fine since JS is single-thread) - - printf("SendCommandToStoneApplication\n"); - printf("%s", message); - - if (applicationWasmAdapter.get() != NULL) { - applicationWasmAdapter->HandleCommandFromWeb(output, std::string(message)); - return output.c_str(); - } - printf("This Stone application does not have a Web Adapter"); - return NULL; - } - #ifdef __cplusplus } #endif diff -r 1c5104a6f7e4 -r d785ee57bd95 Platforms/Wasm/WasmPlatformApplicationAdapter.cpp --- a/Platforms/Wasm/WasmPlatformApplicationAdapter.cpp Mon Mar 18 16:01:07 2019 +0100 +++ b/Platforms/Wasm/WasmPlatformApplicationAdapter.cpp Tue Mar 19 14:43:46 2019 +0100 @@ -2,7 +2,6 @@ #include "Framework/Toolbox/MessagingToolbox.h" #include "Framework/StoneException.h" -#include #include #include "Platforms/Wasm/Defaults.h" @@ -14,35 +13,6 @@ { } - void WasmPlatformApplicationAdapter::HandleCommandFromWeb(std::string& output, const std::string& input) - { - try - { - Json::Value inputJson; - // if the message is a command, build it and execute it - if (MessagingToolbox::ParseJson(inputJson, input.c_str(), input.size())) - { - std::unique_ptr command(application_.GetCommandBuilder().CreateFromJson(inputJson)); - if (command.get() == NULL) - printf("Could not parse command: '%s'\n", input.c_str()); - else - application_.ExecuteCommand(*command); - } - } - catch (StoneException& exc) - { - printf("Error while handling command from web (error code = %d):\n", exc.GetErrorCode()); - printf("While interpreting input: '%s'\n", input.c_str()); - output = std::string("ERROR : "); - } - catch (std::exception& exc) - { - printf("Error while handling message from web (error text = %s):\n", exc.what()); - printf("While interpreting input: '%s'\n", input.c_str()); - output = std::string("ERROR : "); - } - } - void WasmPlatformApplicationAdapter::HandleSerializedMessageFromWeb(std::string& output, const std::string& input) { try diff -r 1c5104a6f7e4 -r d785ee57bd95 Platforms/Wasm/WasmPlatformApplicationAdapter.h --- a/Platforms/Wasm/WasmPlatformApplicationAdapter.h Mon Mar 18 16:01:07 2019 +0100 +++ b/Platforms/Wasm/WasmPlatformApplicationAdapter.h Tue Mar 19 14:43:46 2019 +0100 @@ -13,7 +13,6 @@ WasmPlatformApplicationAdapter(MessageBroker& broker, IStoneApplication& application); virtual void HandleSerializedMessageFromWeb(std::string& output, const std::string& input); - virtual void HandleCommandFromWeb(std::string& output, const std::string& input); virtual void NotifyStatusUpdateFromCppToWebWithString(const std::string& statusUpdateMessage); virtual void NotifyStatusUpdateFromCppToWebWithSerializedMessage(const std::string& statusUpdateMessage); }; diff -r 1c5104a6f7e4 -r d785ee57bd95 Platforms/Wasm/wasm-application-runner.ts --- a/Platforms/Wasm/wasm-application-runner.ts Mon Mar 18 16:01:07 2019 +0100 +++ b/Platforms/Wasm/wasm-application-runner.ts Tue Mar 19 14:43:46 2019 +0100 @@ -21,7 +21,6 @@ var ReleaseCppViewport: Function = null; var StartWasmApplication: Function = null; export var SendSerializedMessageToStoneApplication: Function = null; -export var SendCommandToStoneApplication: Function = null; function DoAnimationThread() { if (WasmDoAnimation != null) { @@ -102,7 +101,6 @@ WasmDoAnimation = ( window).StoneFrameworkModule.cwrap('WasmDoAnimation', null, []); SendSerializedMessageToStoneApplication = ( window).StoneFrameworkModule.cwrap('SendSerializedMessageToStoneApplication', 'string', ['string']); - SendCommandToStoneApplication = ( window).StoneFrameworkModule.cwrap('SendCommandToStoneApplication', 'string', ['string']); Logger.defaultLogger.debug("Connecting C++ methods to JS methods - done"); diff -r 1c5104a6f7e4 -r d785ee57bd95 README.md --- a/README.md Mon Mar 18 16:01:07 2019 +0100 +++ b/README.md Tue Mar 19 14:43:46 2019 +0100 @@ -125,7 +125,10 @@ source code in an `orthanc` folder next to the Stone of Orthanc repository, please enter the following: +**Simple make generator with dynamic build** + ``` +# Please set $currentDir to the current folder mkdir -p ~/builds/orthanc-stone-build cd ~/builds/orthanc-stone-build cmake -DORTHANC_FRAMEWORK_SOURCE=path \ @@ -134,6 +137,16 @@ ~/orthanc-stone/Applications/Samples/ ``` +**Ninja generator with static build (typical under Windows)** + +``` +# Please yourself one level above the orthanc-stone and orthanc folders +mkdir -p stone_build_sdl +cd stone_build_sdl +cmake -G Ninja -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Applications/Samples/ +``` + + If you are working on Windows, add the correct generator option to cmake to, for instance, generate msbuild files for Visual Studio. @@ -146,9 +159,14 @@ Building the Qt native samples (SimpleViewer only) under Windows: ------------------------------------------------------------------ + +**MSVC 2017 generator with static build (typical under Windows)** + For instance, if Qt is installed in `C:\Qt\5.12.0\msvc2017_64` -`cmake -DSTATIC_BUILD=ON -DCMAKE_PREFIX_PATH=C:\Qt\5.12.0\msvc2017_64 -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_QT=ON -G "Visual Studio 15 2017 Win64" ../orthanc-stone/Applications/Samples/` +``` +cmake -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DCMAKE_PREFIX_PATH=C:\Qt\5.12.0\msvc2017_64 -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_QT=ON -G "Visual Studio 15 2017 Win64" ../orthanc-stone/Applications/Samples/ +``` Note: replace `$($pwd)` with the current directory when not using Powershell @@ -196,3 +214,9 @@ url="https://doi.org/10.1007/s10278-018-0082-y" } +Various notes to be deleted +--------------------------- +class BaseCommand : public ICommand + +RadiographySceneCommand +GenericNoArgCommand diff -r 1c5104a6f7e4 -r d785ee57bd95 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Mon Mar 18 16:01:07 2019 +0100 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Tue Mar 19 14:43:46 2019 +0100 @@ -174,10 +174,6 @@ set(APPLICATIONS_SOURCES ${ORTHANC_STONE_ROOT}/Applications/IStoneApplication.h ${ORTHANC_STONE_ROOT}/Applications/StoneApplicationContext.cpp - ${ORTHANC_STONE_ROOT}/Applications/Commands/BaseCommandBuilder.cpp - ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommand.h - ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommandExecutor.h - ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommandBuilder.h ) if (NOT ORTHANC_SANDBOXED)