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

View File

@@ -19,37 +19,51 @@ void ImageViewManager::add(DicomImageView *view) {
void ImageViewManager::remove(DicomImageView *view) { void ImageViewManager::remove(DicomImageView *view) {
if (view && !contains(view)){ if (view && !contains(view)){
vList.removeOne(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) { switch (scope) {
case DoScope::Current:{ case DoScope::Current:{
if (currentView) if (currentView)
cb(currentView); cb(currentView, callData);
break; break;
} }
case DoScope::SameSeries:{ 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; break;
} }
case DoScope::SameSeriesExceptSelf:{ 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; break;
} }
case DoScope::AllExceptSelf: case DoScope::AllExceptSelf:
{
std::for_each(vList.begin(),vList.end(),[=](auto v){ std::for_each(vList.begin(),vList.end(),[=](auto v){
if (v == exceptView) return; if (v == sourceView) return;
cb(v); cb(v, callData);
}); });
break;
}
case DoScope::All: case DoScope::All:
default: default:
std::for_each(vList.begin(),vList.end(),[=](auto v){ 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 Q_OBJECT
public: public:
ImageViewManager(); ImageViewManager(){};
~ImageViewManager(); ~ImageViewManager(){
while(this->getViewCount()>0){
this->remove(0);
}
};
bool contains(DicomImageView* view); bool contains(DicomImageView* view);
void add(DicomImageView* view); void add(DicomImageView* view);
void remove(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{ enum DoScope{
Current, Current,
SameSeries, SameSeries,
@@ -27,8 +54,8 @@ public:
AllExceptSelf, AllExceptSelf,
All All
}; };
typedef void(*SmartDoCallback)(DicomImageView*); typedef void(*SmartDoCallback)(DicomImageView* view, void* callData);
void smartDo(SmartDoCallback cb, DoScope scope = Current,DicomImageView* exceptView = nullptr ); void smartDo(SmartDoCallback cb, DicomImageView *sourceView = nullptr,void* callData = nullptr, DoScope scope = Current);
private: private:
QList<DicomImageView*> vList; QList<DicomImageView*> vList;

View File

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

View File

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