changeset 277:a38465cc909f am-2

Qt: refresh ok + mouse interaction ok
author am@osimis.io
date Mon, 27 Aug 2018 14:41:49 +0200
parents 5de5699ad570
children 8a86695fcbc3
files Applications/Generic/BasicNativeApplicationContext.cpp Applications/Generic/BasicNativeApplicationContext.h Applications/Qt/QCairoWidget.cpp Applications/Qt/QCairoWidget.h Applications/Samples/Qt/MainWindow.cpp Applications/Samples/Qt/MainWindow.h Applications/Sdl/SdlEngine.h Framework/Viewport/IViewport.h Framework/Viewport/WidgetViewport.cpp
diffstat 9 files changed, 104 insertions(+), 269 deletions(-) [+]
line wrap: on
line diff
--- 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)); 
   }
--- 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<WidgetViewport>      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;
     }
+
   };
 }
--- 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<double>(event->x()) + 0.5;
-//  y = static_cast<double>(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<int>(OrthancStone::KeyboardModifiers_None);
+  if ((qtModifiers & Qt::AltModifier) != 0)
+  {
+    stoneModifiers |= static_cast<int>(OrthancStone::KeyboardModifiers_Alt);
+  }
+  if ((qtModifiers & Qt::ControlModifier) != 0)
+  {
+    stoneModifiers |= static_cast<int>(OrthancStone::KeyboardModifiers_Control);
+  }
+  if ((qtModifiers & Qt::ShiftModifier) != 0)
+  {
+    stoneModifiers |= static_cast<int>(OrthancStone::KeyboardModifiers_Shift);
+  }
+  return static_cast<OrthancStone::KeyboardModifiers>(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<double>(event->x()) + 0.5;
-//    double y = static_cast<double>(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<double>(x) + 0.5;
-//    double cy = static_cast<double>(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<int>(scene_->GetSlicesCount()))
-//  {
-//    scene_->SetCurrentSlice(index);
-//    emit SliceChanged(index);
-//    repaint();
-//  }
-//}
--- 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 <memory>
 #include <cassert>
 
-class QCairoWidget : public QWidget
+class QCairoWidget : public QWidget, public OrthancStone::IViewport::IObserver
 {
   Q_OBJECT
 
 private:
   std::auto_ptr<QImage>         image_;
-  OrthancStone::CairoSurface   surface_;
+  OrthancStone::CairoSurface    surface_;
   OrthancStone::BasicNativeApplicationContext* context_;
-  bool                          isMouseOver_;
-  int                           mouseOverX_;
-  int                           mouseOverY_;
-  bool                          updateNeeded_;
-
-  std::auto_ptr<OrthancStone::IMouseTracker>  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);
 };
--- 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_;
 }
 
 
--- 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 <QMainWindow>
-#include <QTimer>
 
 #include "../../Qt/QCairoWidget.h"
 #include "../../Generic/BasicNativeApplicationContext.h"
@@ -20,7 +19,6 @@
 
 private:
   Ui::MainWindow        *ui_;
-  QTimer                *refreshTimer_;
   OrthancStone::BasicNativeApplicationContext& context_;
   QCairoWidget          *cairoCentralWidget_;
 
--- 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;
     }
--- 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()
--- 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);
   }