# HG changeset patch # User am@osimis.io # Date 1535373709 -7200 # Node ID a38465cc909f804e66d45796be47a0cb0163eb4b # Parent 5de5699ad5700c1c6ff0c947f8e7bb4ce1e82140 Qt: refresh ok + mouse interaction ok diff -r 5de5699ad570 -r a38465cc909f Applications/Generic/BasicNativeApplicationContext.cpp --- a/Applications/Generic/BasicNativeApplicationContext.cpp Mon Aug 27 12:21:52 2018 +0200 +++ b/Applications/Generic/BasicNativeApplicationContext.cpp Mon Aug 27 14:41:49 2018 +0200 @@ -40,15 +40,15 @@ that->GetCentralViewport().UpdateContent(); } - boost::this_thread::sleep(boost::posix_time::milliseconds(that->updateDelay_)); + boost::this_thread::sleep(boost::posix_time::milliseconds(that->updateDelayInMs_)); } } - BasicNativeApplicationContext::BasicNativeApplicationContext() : // Orthanc::WebServiceParameters& orthanc, WidgetViewport* centralViewport) : + BasicNativeApplicationContext::BasicNativeApplicationContext() : centralViewport_(new OrthancStone::WidgetViewport()), stopped_(true), - updateDelay_(100) // By default, 100ms between each refresh of the content + updateDelayInMs_(100) // By default, 100ms between each refresh of the content { srand(time(NULL)); } diff -r 5de5699ad570 -r a38465cc909f Applications/Generic/BasicNativeApplicationContext.h --- a/Applications/Generic/BasicNativeApplicationContext.h Mon Aug 27 12:21:52 2018 +0200 +++ b/Applications/Generic/BasicNativeApplicationContext.h Mon Aug 27 14:41:49 2018 +0200 @@ -41,7 +41,7 @@ std::unique_ptr centralViewport_; boost::thread updateThread_; bool stopped_; - unsigned int updateDelay_; + unsigned int updateDelayInMs_; public: class GlobalMutexLocker: public boost::noncopyable @@ -64,9 +64,10 @@ void Stop(); - void SetUpdateDelay(unsigned int delay) // In milliseconds + void SetUpdateDelay(unsigned int delayInMs) { - updateDelay_ = delay; + updateDelayInMs_ = delayInMs; } + }; } diff -r 5de5699ad570 -r a38465cc909f Applications/Qt/QCairoWidget.cpp --- a/Applications/Qt/QCairoWidget.cpp Mon Aug 27 12:21:52 2018 +0200 +++ b/Applications/Qt/QCairoWidget.cpp Mon Aug 27 14:41:49 2018 +0200 @@ -7,33 +7,30 @@ QCairoWidget::QCairoWidget(QWidget *parent) : QWidget(parent), - context_(NULL), - isMouseOver_(false), - mouseOverX_(0), - mouseOverY_(0) + context_(NULL) { - setMouseTracking(true); - updateNeeded_ = true; } - - QCairoWidget::~QCairoWidget() { } +void QCairoWidget::SetContext(OrthancStone::BasicNativeApplicationContext& context) +{ + context_ = &context; + context_->GetCentralViewport().Register(*this); // get notified each time the content of the central viewport changes +} -void QCairoWidget::paintEvent(QPaintEvent* event) +void QCairoWidget::paintEvent(QPaintEvent* /*event*/) { QPainter painter(this); if (image_.get() != NULL && context_ != NULL) { OrthancStone::BasicNativeApplicationContext::GlobalMutexLocker locker(*context_); - OrthancStone::IViewport& vp = context_->GetCentralViewport(); + OrthancStone::IViewport& viewport = context_->GetCentralViewport(); Orthanc::ImageAccessor a = surface_.GetAccessor(); - vp.Render(a); - //image_->fill(0); + viewport.Render(a); painter.drawImage(0, 0, *image_); } else @@ -42,150 +39,80 @@ } } - -//static void GetPixelCenter(double& x, -// double& y, -// const QMouseEvent* event) -//{ -// x = static_cast(event->x()) + 0.5; -// y = static_cast(event->y()) + 0.5; -//} - - -//void QCairoWidget::mousePressEvent(QMouseEvent* event) -//{ -// if (mouseTracker_.get() == NULL) -// { -// OrthancStone::MouseButton button; - -// switch (event->button()) -// { -// case Qt::LeftButton: -// button = OrthancStone::MouseButton_Left; -// break; - -// case Qt::RightButton: -// button = OrthancStone::MouseButton_Right; -// break; +OrthancStone::KeyboardModifiers GetKeyboardModifiers(QInputEvent* event) +{ + Qt::KeyboardModifiers qtModifiers = event->modifiers(); + int stoneModifiers = static_cast(OrthancStone::KeyboardModifiers_None); + if ((qtModifiers & Qt::AltModifier) != 0) + { + stoneModifiers |= static_cast(OrthancStone::KeyboardModifiers_Alt); + } + if ((qtModifiers & Qt::ControlModifier) != 0) + { + stoneModifiers |= static_cast(OrthancStone::KeyboardModifiers_Control); + } + if ((qtModifiers & Qt::ShiftModifier) != 0) + { + stoneModifiers |= static_cast(OrthancStone::KeyboardModifiers_Shift); + } + return static_cast(stoneModifiers); +} -// case Qt::MiddleButton: -// button = OrthancStone::MouseButton_Middle; -// break; +void QCairoWidget::mousePressEvent(QMouseEvent* event) +{ + OrthancStone::KeyboardModifiers stoneModifiers = GetKeyboardModifiers(event); + + OrthancStone::MouseButton button; -// default: -// return; // Unsupported button -// } + switch (event->button()) + { + case Qt::LeftButton: + button = OrthancStone::MouseButton_Left; + break; -// double x, y; -// GetPixelCenter(x, y, event); -////TODO mouseTracker_.reset(viewport_.CreateMouseTracker(*scene_, button, x, y)); -// repaint(); -// } -//} - + case Qt::RightButton: + button = OrthancStone::MouseButton_Right; + break; -//void QCairoWidget::mouseReleaseEvent(QMouseEvent* event) -//{ -// if (mouseTracker_.get() != NULL) -// { -// mouseTracker_->MouseUp(); -// mouseTracker_.reset(NULL); -// repaint(); -// } -//} + case Qt::MiddleButton: + button = OrthancStone::MouseButton_Middle; + break; + + default: + return; // Unsupported button + } + context_->GetCentralViewport().MouseDown(button, event->pos().x(), event->pos().y(), stoneModifiers); +} -//void QCairoWidget::mouseMoveEvent(QMouseEvent* event) -//{ -// if (mouseTracker_.get() == NULL) -// { -// if (rect().contains(event->pos())) -// { -// // Mouse over widget -// isMouseOver_ = true; -// mouseOverX_ = event->x(); -// mouseOverY_ = event->y(); -// } -// else -// { -// // Mouse out of widget -// isMouseOver_ = false; -// } -// } -// else -// { -// double x, y; -// GetPixelCenter(x, y, event); -// mouseTracker_->MouseMove(x, y); -// isMouseOver_ = false; -// } +void QCairoWidget::mouseReleaseEvent(QMouseEvent* /*eventNotUsed*/) +{ + context_->GetCentralViewport().MouseLeave(); +} -//// if (isMouseOver_) -//// { -//// UpdateMouseCoordinates(event->x(), event->y()); -//// } -// repaint(); -//} +void QCairoWidget::mouseMoveEvent(QMouseEvent* event) +{ + context_->GetCentralViewport().MouseMove(event->pos().x(), event->pos().y()); +} -//void QCairoWidget::wheelEvent(QWheelEvent * event) -//{ -// if (mouseTracker_.get() == NULL) -// { -//#if 0 -// double x = static_cast(event->x()) + 0.5; -// double y = static_cast(event->y()) + 0.5; -// mouseTracker_.reset(viewport_.CreateMouseTracker(*scene_, MouseButton_Middle, x, y)); - -// switch (event->orientation()) -// { -// case Qt::Horizontal: -// x += event->delta(); -// break; - -// case Qt::Vertical: -// y += event->delta(); -// break; - -// default: -// break; -// } - -// mouseTracker_->MouseMove(x, y); -// mouseTracker_->MouseUp(); -// mouseTracker_.reset(NULL); +void QCairoWidget::wheelEvent(QWheelEvent * event) +{ + OrthancStone::KeyboardModifiers stoneModifiers = GetKeyboardModifiers(event); -// repaint(); -//#else -// if (event->orientation() == Qt::Vertical) -// { -// unsigned int slice = scene_->GetCurrentSlice(); - -// if (event->delta() < 0) -// { -// if (slice > 0) -// { -// scene_->SetCurrentSlice(slice - 1); -// emit SliceChanged(slice - 1); -// } -// } -// else -// { -// if (slice + 1 < scene_->GetSlicesCount()) -// { -// scene_->SetCurrentSlice(slice + 1); -// emit SliceChanged(slice + 1); -// } -// } - -// repaint(); -// } -//#endif -// } - -// UpdateMouseCoordinates(event->x(), event->y()); -//} + if (event->orientation() == Qt::Vertical) + { + if (event->delta() < 0) // TODO: compare direction with SDL and make sure we send the same directions + { + context_->GetCentralViewport().MouseWheel(OrthancStone::MouseWheelDirection_Up, event->pos().x(), event->pos().y(), stoneModifiers); + } + else + { + context_->GetCentralViewport().MouseWheel(OrthancStone::MouseWheelDirection_Down, event->pos().x(), event->pos().y(), stoneModifiers); + } + } +} @@ -208,50 +135,3 @@ } } - -//void QCairoWidget::UpdateMouseCoordinates(int x, -// int y) -//{ -// if (scene_ != NULL) -// { -// double cx = static_cast(x) + 0.5; -// double cy = static_cast(y) + 0.5; - -// std::string coordinates; -// viewport_.FormatCoordinates(coordinates, *scene_, cx, cy); - -// emit PositionChanged(QString(coordinates.c_str())); -// } -//} - - -//void QCairoWidget::SetDefaultView() -//{ -// viewport_.SetDefaultView(); -// repaint(); -//} - - -//void QCairoWidget::Refresh() -//{ -// if (scene_ != NULL && -// updateNeeded_) -// { -// updateNeeded_ = false; -// emit ContentChanged(); -// repaint(); -// } -//} - - -//void QCairoWidget::SetSlice(int index) -//{ -// if (scene_ != NULL && -// index >= 0 && -// index < static_cast(scene_->GetSlicesCount())) -// { -// scene_->SetCurrentSlice(index); -// emit SliceChanged(index); -// repaint(); -// } -//} diff -r 5de5699ad570 -r a38465cc909f Applications/Qt/QCairoWidget.h --- a/Applications/Qt/QCairoWidget.h Mon Aug 27 12:21:52 2018 +0200 +++ b/Applications/Qt/QCairoWidget.h Mon Aug 27 14:41:49 2018 +0200 @@ -9,84 +9,45 @@ #include #include -class QCairoWidget : public QWidget +class QCairoWidget : public QWidget, public OrthancStone::IViewport::IObserver { Q_OBJECT private: std::auto_ptr image_; - OrthancStone::CairoSurface surface_; + OrthancStone::CairoSurface surface_; OrthancStone::BasicNativeApplicationContext* context_; - bool isMouseOver_; - int mouseOverX_; - int mouseOverY_; - bool updateNeeded_; - - std::auto_ptr mouseTracker_; - -// void UpdateMouseCoordinates(int x, -// int y); protected: - void paintEvent(QPaintEvent *event); + virtual void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent *event); + virtual void resizeEvent(QResizeEvent *event); -// void mouseMoveEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); -// void mousePressEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); -// void mouseReleaseEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); -// void wheelEvent(QWheelEvent *event); + virtual void wheelEvent(QWheelEvent *event); public: explicit QCairoWidget(QWidget *parent); virtual ~QCairoWidget(); - void SetContext(OrthancStone::BasicNativeApplicationContext& context) + void SetContext(OrthancStone::BasicNativeApplicationContext& context); + + virtual void OnViewportContentChanged(const OrthancStone::IViewport& /*sceneNotUsed*/) { - context_ = &context; + update(); // schedule a repaint (handled by Qt) + emit ContentChanged(); } -// void SetCentralWidget(OrthancStone::CairoWidget& widget) -// { -// centralWidget_ = &widget; -// } - -// void SetScene(OrthancStone::ICairoScene& scene); - -// bool HasScene() const -// { -// return scene_ != NULL; -// } +signals: -// OrthancStone::ICairoScene& GetScene() const -// { -// assert(HasScene()); -// return *scene_; -// } - -// virtual void SignalUpdatedScene(OrthancStone::ICairoScene& scene) -// { -// //printf("UPDATE NEEDED\n"); fflush(stdout); -// updateNeeded_ = true; -// } - -signals: -// void SliceChanged(int position); - -// void RangeChanged(unsigned int countSlices); - -// void PositionChanged(const QString& position); - -// void ContentChanged(); + void ContentChanged(); public slots: -// void SetDefaultView(); -// void Refresh(); - -// void SetSlice(int index); }; diff -r 5de5699ad570 -r a38465cc909f Applications/Samples/Qt/MainWindow.cpp --- a/Applications/Samples/Qt/MainWindow.cpp Mon Aug 27 12:21:52 2018 +0200 +++ b/Applications/Samples/Qt/MainWindow.cpp Mon Aug 27 14:41:49 2018 +0200 @@ -11,19 +11,14 @@ ui_(new Ui::MainWindow), context_(context) { - refreshTimer_ = new QTimer(this); ui_->setupUi(this); cairoCentralWidget_ = ui_->cairoCentralWidget; cairoCentralWidget_->SetContext(context_); - - //connect(refreshTimer_, SIGNAL(timeout()), ui_->ca, SLOT(Refresh())); - refreshTimer_->start(100); } MainWindow::~MainWindow() { delete ui_; - delete refreshTimer_; } diff -r 5de5699ad570 -r a38465cc909f Applications/Samples/Qt/MainWindow.h --- a/Applications/Samples/Qt/MainWindow.h Mon Aug 27 12:21:52 2018 +0200 +++ b/Applications/Samples/Qt/MainWindow.h Mon Aug 27 14:41:49 2018 +0200 @@ -2,7 +2,6 @@ #define MAINWINDOW_H #include -#include #include "../../Qt/QCairoWidget.h" #include "../../Generic/BasicNativeApplicationContext.h" @@ -20,7 +19,6 @@ private: Ui::MainWindow *ui_; - QTimer *refreshTimer_; OrthancStone::BasicNativeApplicationContext& context_; QCairoWidget *cairoCentralWidget_; diff -r 5de5699ad570 -r a38465cc909f Applications/Sdl/SdlEngine.h --- a/Applications/Sdl/SdlEngine.h Mon Aug 27 12:21:52 2018 +0200 +++ b/Applications/Sdl/SdlEngine.h Mon Aug 27 14:41:49 2018 +0200 @@ -50,7 +50,7 @@ virtual ~SdlEngine(); - virtual void NotifyChange(const IViewport& viewport) + virtual void OnViewportContentChanged(const IViewport& viewport) { viewportChanged_ = true; } diff -r 5de5699ad570 -r a38465cc909f Framework/Viewport/IViewport.h --- a/Framework/Viewport/IViewport.h Mon Aug 27 12:21:52 2018 +0200 +++ b/Framework/Viewport/IViewport.h Mon Aug 27 14:41:49 2018 +0200 @@ -40,7 +40,7 @@ { } - virtual void NotifyChange(const IViewport& scene) = 0; + virtual void OnViewportContentChanged(const IViewport& scene) = 0; }; virtual ~IViewport() diff -r 5de5699ad570 -r a38465cc909f Framework/Viewport/WidgetViewport.cpp --- a/Framework/Viewport/WidgetViewport.cpp Mon Aug 27 12:21:52 2018 +0200 +++ b/Framework/Viewport/WidgetViewport.cpp Mon Aug 27 14:41:49 2018 +0200 @@ -74,7 +74,7 @@ } backgroundChanged_ = true; - observers_.Apply(*this, &IObserver::NotifyChange); + observers_.Apply(*this, &IObserver::OnViewportContentChanged); return *widget; } @@ -83,7 +83,7 @@ void WidgetViewport::NotifyChange(const IWidget& widget) { backgroundChanged_ = true; - observers_.Apply(*this, &IObserver::NotifyChange); + observers_.Apply(*this, &IObserver::OnViewportContentChanged); } @@ -97,7 +97,7 @@ centralWidget_->SetSize(width, height); } - observers_.Apply(*this, &IObserver::NotifyChange); + observers_.Apply(*this, &IObserver::OnViewportContentChanged); } @@ -154,7 +154,7 @@ mouseTracker_.reset(NULL); } - observers_.Apply(*this, &IObserver::NotifyChange); + observers_.Apply(*this, &IObserver::OnViewportContentChanged); } @@ -164,7 +164,7 @@ { mouseTracker_->MouseUp(); mouseTracker_.reset(NULL); - observers_.Apply(*this, &IObserver::NotifyChange); + observers_.Apply(*this, &IObserver::OnViewportContentChanged); } } @@ -195,7 +195,7 @@ if (repaint) { // The scene must be repainted, notify the observers - observers_.Apply(*this, &IObserver::NotifyChange); + observers_.Apply(*this, &IObserver::OnViewportContentChanged); } } @@ -203,7 +203,7 @@ void WidgetViewport::MouseEnter() { isMouseOver_ = true; - observers_.Apply(*this, &IObserver::NotifyChange); + observers_.Apply(*this, &IObserver::OnViewportContentChanged); } @@ -217,7 +217,7 @@ mouseTracker_.reset(NULL); } - observers_.Apply(*this, &IObserver::NotifyChange); + observers_.Apply(*this, &IObserver::OnViewportContentChanged); }