Use ImageViewManager to control all views.

This commit is contained in:
Krad
2022-03-11 14:07:29 +08:00
parent 58afeac99f
commit be526bcf07
5 changed files with 173 additions and 191 deletions

View File

@@ -1,4 +1,4 @@
#include "QDicomViewer.h"
#include "QDicomViewer.h"
#include "global/include_all.h"
#include "base/SeriesImageSet.h"
#include "view/subview/gridpopwidget.h"
@@ -269,34 +269,24 @@ void QDicomViewer::SetupAnnoTool(QToolButton* annoBtn)
//主要设置了四角标签的操作逻辑
annoBtn->setToolTip(QString("Toggle annotations"));
//视窗操作,显隐脚注
connect(annoBtn, &QToolButton::clicked, this, [=] {
AnnoHelper::toggleAnno();
QList<DicomImageView*> viewers = ui->viewContainer->getViewList();
std::for_each(viewers.begin(), viewers.end(), [=](DicomImageView* v) {
v->updateCornerInfoAll();
});
});
ui->viewContainer->updateCornerInfoAll();
});
//视窗操作,显隐测量
QMenu* m;
m = new QMenu(this);
connect(m, &QMenu::triggered, this, [=]
{
//load data
m_measure_hidden_action->setChecked(Measure::GetHidden());
});
{
//load data
m_measure_hidden_action->setChecked(Measure::GetHidden());
});
//视窗操作,显隐测量
m_measure_hidden_action = m->addAction(tr("Hide all measurements"), this, [=](bool value) {
//QPixmap map(":/InfiniteViewer/Icon/hidden.png");
//m_cur_measure = AnnotationActorType::HiddenAnn;
//annoBtn->setIcon(QIcon(map));
QList<DicomImageView*> viewers = ui->viewContainer->getViewList();
std::for_each(viewers.begin(), viewers.end(), [=](DicomImageView* v) {
Measure::SetHidden(value);
v->Render();
});
Measure::SetHidden(value);
ui->viewContainer->render();
});
m->addSeparator();
@@ -311,11 +301,8 @@ void QDicomViewer::SetupAnnoTool(QToolButton* annoBtn)
{
AnnoHelper::PrivacyOff();
}
QList<DicomImageView*> viewers = ui->viewContainer->getViewList();
std::for_each(viewers.begin(), viewers.end(), [=](DicomImageView* v) {
v->updateCornerInfoPrivacy();
});
});
ui->viewContainer->updateCornerInfoPrivacy();
});
m_patient_hidden_action->setCheckable(true);
m_patient_hidden_action->setChecked(false);
@@ -415,8 +402,6 @@ void QDicomViewer::executeActiveMeasure(ViewContainerWidget* Container, Annotati
});
break;
}
}
//视窗操作AnnotationActor新增相关
@@ -426,7 +411,7 @@ void QDicomViewer::SetupMeasureTool(QToolButton* measureBtn)
connect(measureBtn, &QToolButton::clicked, this, [=] {
executeActiveMeasure(ui->viewContainer, m_cur_measure);
});
});
QMenu* m;
m = new QMenu(this);
@@ -525,7 +510,6 @@ void QDicomViewer::SetupMeasureTool(QToolButton* measureBtn)
m->addSeparator();
m->addAction(tr("Delete selected"), this, [=] {
measureBtn->setChecked(true);
m_cur_measure = AnnotationActorType::DeleteSelectedAnn;

View File

@@ -19,37 +19,51 @@ void ImageViewManager::add(DicomImageView *view) {
void ImageViewManager::remove(DicomImageView *view) {
if (view && !contains(view)){
vList.removeOne(view);
delete view;
}
}
void ImageViewManager::smartDo(ImageViewManager::SmartDoCallback cb, ImageViewManager::DoScope scope,DicomImageView* exceptView) {
void ImageViewManager::remove(int idx) {
if (idx >= vList.size()) return;
auto view = vList.at(idx);
vList.removeOne(view);
delete view;
}
void ImageViewManager::smartDo(SmartDoCallback cb, DicomImageView *sourceView, void* callData, DoScope scope) {
switch (scope) {
case DoScope::Current:{
if (currentView)
cb(currentView);
cb(currentView, callData);
break;
}
case DoScope::SameSeries:{
//TODO: need add same series and same direction check and do logic!
std::for_each(vList.begin(),vList.end(),[=](auto v){
//check series
cb(v, callData);
});
break;
}
case DoScope::SameSeriesExceptSelf:{
//TODO: need add same series and same direction check and do logic!
std::for_each(vList.begin(),vList.end(),[=](auto v){
if (v == sourceView) return;
//check series
cb(v, callData);
});
break;
}
case DoScope::AllExceptSelf:
{
std::for_each(vList.begin(),vList.end(),[=](auto v){
if (v == exceptView) return;
cb(v);
if (v == sourceView) return;
cb(v, callData);
});
break;
}
case DoScope::All:
default:
std::for_each(vList.begin(),vList.end(),[=](auto v){
cb(v);
cb(v, callData);
});
}
}
void ImageViewManager::setCurrentView(DicomImageView* view) {
currentView = view;
}

View File

@@ -13,13 +13,40 @@ class ImageViewManager:public QObject {
Q_OBJECT
public:
ImageViewManager();
~ImageViewManager();
ImageViewManager(){};
~ImageViewManager(){
while(this->getViewCount()>0){
this->remove(0);
}
};
bool contains(DicomImageView* view);
void add(DicomImageView* view);
void remove(DicomImageView* view);
void setCurrentView(DicomImageView* view);
void remove(int idx);
void setCurrentView(DicomImageView* view){
currentView = view;
}
void clear(){
vList.clear();
}
DicomImageView* getCurrentView(){
return currentView;
}
int getViewCount(){
return vList.size();
}
DicomImageView* getView(int index){
if (index >= vList.size()) return nullptr;
return vList[index];
}
DicomImageView* getFirstView(){
if (vList.size() == 0) return nullptr;
return vList[0];
}
QList<DicomImageView*>& getViewList(){
return vList;
}
enum DoScope{
Current,
SameSeries,
@@ -27,8 +54,8 @@ public:
AllExceptSelf,
All
};
typedef void(*SmartDoCallback)(DicomImageView*);
void smartDo(SmartDoCallback cb, DoScope scope = Current,DicomImageView* exceptView = nullptr );
typedef void(*SmartDoCallback)(DicomImageView* view, void* callData);
void smartDo(SmartDoCallback cb, DicomImageView *sourceView = nullptr,void* callData = nullptr, DoScope scope = Current);
private:
QList<DicomImageView*> vList;

View File

@@ -1,4 +1,4 @@
#include "viewcontainerwidget.h"
#include "viewcontainerwidget.h"
#include "thumbnailImage.h"
#include "DicomLoader.h"
#include <QWidget>
@@ -30,26 +30,26 @@ ViewContainerWidget::~ViewContainerWidget() {
}
//-------------------------------------------------------
QList<DicomImageView *> ViewContainerWidget::getViewList() const {
return view_list_;
QList<DicomImageView *>& ViewContainerWidget::getViewList() {
return manager.getViewList();
}
DicomImageView *ViewContainerWidget::getCurrentView() const {
return current_view_;
DicomImageView *ViewContainerWidget::getCurrentView() {
return manager.getCurrentView();
}
DicomImageView* ViewContainerWidget::getNextView() const
DicomImageView* ViewContainerWidget::getNextView()
{
bool found = false;
for (int i = 0; i < view_list_.size(); ++i)
for (int i = 0; i < manager.getViewCount(); ++i)
{
DicomImageView *v = view_list_.at(i);
DicomImageView *v = manager.getView(i);
if (found)
{
return v;
}
if (current_view_ == v)
if (manager.getCurrentView() == v)
{
found = true;
}
@@ -67,53 +67,26 @@ void ViewContainerWidget::Slot_SyncEvent(DicomImageView *view, int interactionMo
{
if (SyncHelper::getSyncState() == AUTO_SYNC)
{
for (auto *v : view_list_) {
//foreach(DicomImageView *v, view_list_){
if (v->HasSeries())
{
if (view != v)
{
int* r = (int*)calldata;
v->setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY);
v->SetSlice(r[0]);
#ifdef _DEBUG
printf("Sliced, current slice number:%d \r\n", r[0]);
#endif // _DEBUG
//v->GetScrollbar()->setValue(r[0]);
v->setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER);
}
}
}
manager.smartDo([](auto v,auto callData){
if (v->HasSeries()) {
int *r = (int *) callData;
v->setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY);
v->SetSlice(r[0]);
v->setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER);
}
},view, calldata,ImageViewManager::AllExceptSelf);
}
if (SyncHelper::getSyncState() == MANUAL_SYNC)
{
//foreach(DicomImageView *v, view_list_) {
for (auto *v : view_list_) {
if (v->HasSeries())
{
if (v != view)
{
//disable global trigger slot
v->setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY);
int* r = (int*)calldata;
//r[0]:cur_value
//r[1]:view_step
//r[2]:min_value
//r[3]:max_value
//int set_value = r[0] + r[1];
//v->GetScrollbar()->setValue(set_value);
v->AddSlice(r[1]);
#ifdef _DEBUG
printf("Sliced, current added slice number:%d \r\n", r[1]);
#endif
v->setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER);
}
}
}
manager.smartDo([](auto v,auto callData){
if (v->HasSeries()) {
//disable global trigger slot
v->setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY);
int *r = (int *) callData;
v->AddSlice(r[1]);
v->setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER);
}
},view, calldata,ImageViewManager::AllExceptSelf);
}
}
@@ -121,50 +94,35 @@ void ViewContainerWidget::Slot_SyncEvent(DicomImageView *view, int interactionMo
case VTKIS_IMAGE_PAN:
if (SyncHelper::getSyncItem(ZOOM_PAN))
{
//foreach(DicomImageView *v, view_list_) {
for (auto *v : view_list_) {
if (v != view)
{
double *d = (double *)calldata;
double vector[3] = { d[3] - d[0],d[4] - d[1],d[5] - d[2] };
v->SetPanOffset(vector);
#ifdef _DEBUG
printf("EndPan, last focalpoint:%f,%f,%f;current focalpoint:%f,%f,%f \r\n", d[0], d[1], d[2], d[3],
d[4], d[5]);
#endif
}
}
manager.smartDo([](auto v,auto callData){
if (v->HasSeries()) {
double *d = (double *)callData;
double vector[3] = { d[3] - d[0],d[4] - d[1],d[5] - d[2] };
v->SetPanOffset(vector);
}
},view, calldata,ImageViewManager::AllExceptSelf);
}
break;
case VTKIS_IMAGE_ZOOM:
if (SyncHelper::getSyncItem(ZOOM_PAN))
{
//foreach(DicomImageView *v, view_list_) {
for (auto *v : view_list_) {
if (v != view)
{
double *d = (double *)calldata;
v->SetZoomScale(d[1]);
#ifdef _DEBUG
printf("EndDolly, scale param:%f,%f \r\n", d[0], d[1]);
#endif
}
}
manager.smartDo([](auto v,auto callData){
if (v->HasSeries()) {
double *d = (double *)callData;
v->SetZoomScale(d[1]);
}
},view, calldata,ImageViewManager::AllExceptSelf);
}
break;
case VTKIS_IMAGE_WINDOWLEVEL:
if (SyncHelper::getSyncItem(WIDTH_LEVEL))
{
for (auto *v : view_list_) {
//foreach(DicomImageView *v, view_list_) {
if (v != view)
{
double *d = (double *)calldata;
printf("EndWindowLevel, scale param:%f,%f \r\n", d[0], d[1]);
manager.smartDo([](auto v,auto callData){
if (v->HasSeries()) {
double *d = (double *)callData;
v->SetWindowLevel(d[1], d[0]);
}
}
}
},view, calldata,ImageViewManager::AllExceptSelf);
}
break;
default:
@@ -175,32 +133,34 @@ void ViewContainerWidget::Slot_SyncEvent(DicomImageView *view, int interactionMo
void ViewContainerWidget::SetInteractionMode(int InteractionMode)
{
for (auto *v : view_list_) {
if (v->getImageViewer())
{
v->getImageViewer()->GetInteractorStyle()->SetInteractionModeFromEnum(InteractionMode);
}
}
void * data = (void *)&InteractionMode;
manager.smartDo([](auto v,auto callData){
int* mode = (int *)callData;
if (v->getImageViewer())
{
v->getImageViewer()->GetInteractorStyle()->SetInteractionModeFromEnum(*mode);
}
}, nullptr, data);
}
void ViewContainerWidget::Slot_ViewClicked(DicomImageView *view) {
//set current_view
if (current_view_ != view) {
setCurrentView(view);
if (manager.getCurrentView() != view) {
manager.setCurrentView(view);
}
}
void ViewContainerWidget::setCurrentView(DicomImageView *view) {
//notify before set nullptr
if (current_view_) {
current_view_->setHighlight(false);
if (manager.getCurrentView()) {
manager.getCurrentView()->setHighlight(false);
}
current_view_ = view;
if (current_view_) {
current_view_->setHighlight(true);
manager.setCurrentView(view);
if (manager.getCurrentView()) {
manager.getCurrentView()->setHighlight(true);
}
emit Signal_NotifyThumbnail(current_view_);
emit Signal_NotifyThumbnail(manager.getCurrentView());
}
//-------------------------------------------------------
@@ -214,22 +174,13 @@ void ViewContainerWidget::Slot_ViewDoubleClicked(DicomImageView *view) {
return;
}
if (maxed_) {
//DicomImageView::setFontRatio(_fontRatio);
//std::for_each(view_list_.begin(), view_list_.end(), [=](DicomImageView* v) {
for (auto *v : view_list_) {
v->setVisible(true);
}
manager.smartDo([](auto v,auto callData){v->setVisible(true);});
maxed_ = false;
}
else {
//std::for_each(view_list_.begin(), view_list_.end(), [=](DicomImageView* v){
for (auto *v : view_list_) {
v->setVisible(false);
}
manager.smartDo([](auto v,auto callData){v->setVisible(false);});
view->setVisible(true);
maxed_ = true;
}
}
@@ -245,19 +196,20 @@ void ViewContainerWidget::Slot_SetViewLayout(int col, int row) {
return;
}
for (auto *v : view_list_) {
for (int i = 0; i < manager.getViewCount(); i++) {
DicomImageView *v = manager.getView(i);
this->layout()->removeWidget(v);
}
int viewCount = col * row;
while (viewCount < view_list_.size()) {
DicomImageView *v = view_list_.takeLast();
while (viewCount < manager.getViewCount()) {
DicomImageView *v = manager.getView(manager.getViewCount()-1);
//YTC:better compare before delete
if (current_view_ == v)
if (manager.getCurrentView() == v)
{
setCurrentView(view_list_.first());
manager.setCurrentView(manager.getView(0));
}
//current_view_ = (current_view_ == v) ? nullptr : current_view_;
delete v;
manager.remove(v);
}
//
DicomImageView *view;
@@ -271,12 +223,12 @@ void ViewContainerWidget::Slot_SetViewLayout(int col, int row) {
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (i * col + j < view_list_.size()) {
view = view_list_[i * col + j];
if (i * col + j < manager.getViewCount()) {
view = manager.getView(i * col + j);
}
else {
view = createImageView(this);
view_list_ << view;
manager.add(view);
}
if (view->IsCine())
@@ -294,8 +246,8 @@ void ViewContainerWidget::Slot_SetViewLayout(int col, int row) {
}
}
if ((!current_view_) && (!view_list_.isEmpty())) {
Slot_ViewClicked(view_list_.first());
if ((!manager.getCurrentView()) && (manager.getViewCount()>0)) {
Slot_ViewClicked(manager.getView(0));
}
}
@@ -328,7 +280,7 @@ void ViewContainerWidget::resizeEvent(QResizeEvent *e) {
void ViewContainerWidget::emptyCurrentView()
{
Slot_ViewEmpty(current_view_);
Slot_ViewEmpty(manager.getCurrentView());
}
@@ -349,33 +301,32 @@ void ViewContainerWidget::Slot_DragDropEvent(DicomImageView *view, thumbnailImag
void ViewContainerWidget::Slot_ThumbnailClickEvent(thumbnailImage* tb)
{
DicomImageView *view = getCurrentView();
DicomImageView *view = manager.getCurrentView();
if (nullptr == view)
{
return;
}
auto serie_info = tb->getSeriesInfo();
replaceViewWithSerie(serie_info->GetUniqueID(), view);
setCurrentView(view);
manager.setCurrentView(view);
}
void ViewContainerWidget::resetToOneView() {
Slot_SetViewLayout(1,1);
for (int i = 1; i < view_list_.size(); ++i) {
delete view_list_[i];
while(manager.getViewCount()>1){
manager.remove(1);
}
DicomImageView* v = view_list_[0];
view_list_.clear();
view_list_.push_back(v);
setCurrentView(v);
DicomImageView* v = manager.getView(0);
manager.clear();
manager.add(v);
manager.setCurrentView(v);
}
void ViewContainerWidget::replaceViewWithSerie(const std::string& uniqueid, DicomImageView* curV)
{
if (!curV)
{
curV= getCurrentView();
curV= manager.getCurrentView();
}
curV->removeViewWithFusion();
DicomLoader *helper = DicomLoader::GetInstance();
@@ -385,10 +336,10 @@ void ViewContainerWidget::replaceViewWithSerie(const std::string& uniqueid, Dico
void ViewContainerWidget::toggleViewWithFusion()
{
if (current_view_)
if (manager.getCurrentView())
{
if (current_view_->HasSeries() && current_view_->IsFusion())
if (manager.getCurrentView()->HasSeries() && manager.getCurrentView()->IsFusion())
{
removeCurrentViewWithFusion();
}
@@ -404,13 +355,13 @@ void ViewContainerWidget::replaceViewWithFusion()
{
//Temporal: automatically fusion with next image
DicomImageView * overlap_view = this->getNextView();
if (checkFusionStatus(current_view_, overlap_view))
if (checkFusionStatus(manager.getCurrentView(), overlap_view))
{
connect(overlap_view, &DicomImageView::Signal_WindowLevelEventForFusion,
current_view_, &DicomImageView::Slot_WindowLevelEventForFusion);
manager.getCurrentView(), &DicomImageView::Slot_WindowLevelEventForFusion);
current_view_->SetFusionInput(overlap_view);
current_view_->Render();
manager.getCurrentView()->SetFusionInput(overlap_view);
manager.getCurrentView()->Render();
}
else
{
@@ -419,8 +370,8 @@ void ViewContainerWidget::replaceViewWithFusion()
}
void ViewContainerWidget::removeCurrentViewWithFusion()
{
if (current_view_) {
current_view_->removeViewWithFusion();
if (manager.getCurrentView()) {
manager.getCurrentView()->removeViewWithFusion();
}
}

View File

@@ -1,9 +1,10 @@
#pragma once
#pragma once
#include <QFrame>
#include <QScrollBar>
#include "global/QGlobals.h"
//#include "modalityproperty.h"
#include "dicomimageview.h"
#include "ImageViewManager.h"
class QGridLayout;
class DicomImageView;
@@ -18,14 +19,18 @@ public:
~ViewContainerWidget();
DicomImageView* getCurrentView() const;
DicomImageView* getNextView() const;
QList<DicomImageView*> getViewList() const;
DicomImageView* getCurrentView();
DicomImageView* getNextView();
QList<DicomImageView*>& getViewList() ;
void setCurrentView(DicomImageView *view);
void emptyCurrentView();
void updateCornerInfoAll();
void updateCornerInfoPrivacy();
void activeMeasure();
void render();
void replaceViewWithSerie(const std::string& unique_info,
DicomImageView* curV = nullptr);
@@ -66,5 +71,6 @@ private:
DicomImageView *createImageView(QWidget* parent);
QList<DicomImageView*> view_list_;
DicomImageView *current_view_ = nullptr;
ImageViewManager manager;
bool maxed_ = false;
};