# Add button to maximize view

**URL:** https://discourse.slicer.org/t/add-button-to-maximize-view/18092
**Category:** Development
**Created:** [June 9, 2021, 6:49am UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092 "2021-06-09T06:49:28Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [June 9, 2021, 6:49am UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/1 "2021-06-09T06:49:28Z")

</div>

@lassoan

- For accessing `qMRMLLayoutManager::setLayout` function in `qMRMLThreeDViewControllerWidget`, I need an instance of `qMRMLLayoutManager`.

- So, how can I get the `qMRMLLayoutManager` instance in `qMRMLThreeDViewControllerWidget`. Or is there any other way of accessing `qMRMLLayoutManager::setLayout`.

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [June 9, 2021, 9:33pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/2 "2021-06-09T21:33:50Z")

</div>

How this should probably work is that the widget would set a `maximizedLayoutName` (layout name of the maximized view) in the `vtkMRMLLayoutNode`. You can get the layout node from the scene: if `ParentLayoutNode` is set in the view node then you will use that node, otherwise you will look up the default layout manager node (it is a singleton).

The layout manager gets a notification about the layout node change and it will hide all layout elements from the view except the widget that corresponds to `maximizedLayoutName`.

---

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [June 10, 2021, 3:37am UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/3 "2021-06-10T03:37:10Z")

</div>

Instead of creating a new function (`maximizedLayoutName`) there is already a `setLayout` function in `qMRMLLayoutManager`. Will there be any problem if I use that?

code:

```auto
void qMRMLLayoutManager::setLayout(int layout)
{
  Q_D(qMRMLLayoutManager);
  if (this->layout() == layout)
    {
    return;
    }
  // Update LayoutNode
  if (d->MRMLLayoutNode)
    {
    if (!d->MRMLLayoutNode->IsLayoutDescription(layout))
      {
      layout = vtkMRMLLayoutNode::SlicerLayoutConventionalView;
      }
    d->MRMLLayoutNode->SetViewArrangement(layout);
    }
}

```

`MRMLLayoutNode` is a pointer of `vtkMRMLLayoutNode* MRMLLayoutNode;`

code for `IsLayoutDescription` in `vtkMRMLLayoutNode`:

```auto
bool vtkMRMLLayoutNode::IsLayoutDescription(int layout)
{
  std::map<int, std::string>::const_iterator it = this->Layouts.find(layout);
  return it != this->Layouts.end();
}

```

code for `SetViewArrangement` in `vtkMRMLLayoutNode`:

```auto
void vtkMRMLLayoutNode::SetViewArrangement(int arrNew)
{
 // if the view arrangement definition has not been changed, return
 if ( this->ViewArrangement == arrNew
   && this->GetCurrentLayoutDescription()
   && this->GetCurrentLayoutDescription() == this->GetLayoutDescription(arrNew) )
   {
   return;
   }
 this->ViewArrangement = arrNew;
#if 1
 if (!this->IsLayoutDescription(this->ViewArrangement))
   {
   vtkWarningMacro(<< "View arrangement " << this->ViewArrangement
                   << " is not recognized, register it with "
                   << "AddLayoutDescription()");
   }
#endif
 int wasModifying = this->StartModify();
 this->UpdateCurrentLayoutDescription();
 this->Modified();
 this->EndModify(wasModifying);
}

```

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [June 10, 2021, 3:57am UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/4 "2021-06-10T03:57:29Z")

</div>

Maximizing a view is a temporary operation. It should be possible to maximize/restore a selected view without changing the layout.

---

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [June 10, 2021, 11:19am UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/5 "2021-06-10T11:19:27Z")

</div>

- How can I create an instance of `qMRMLLayoutManager` in `qMRMLThreeDViewControllerWidget`.

---

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [June 10, 2021, 3:06pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/6 "2021-06-10T15:06:48Z")

</div>

@lassoan

- For accessing `vtkMRMLLayoutNode` I need an instance, and I can’t figure out how to initialize `vtkMRMLLayoutNode` pointer.

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [June 10, 2021, 3:15pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/7 "2021-06-10T15:15:57Z")

</div>

The qMRMLThreeDViewControllerWidget does not know how many layout managers the application has or how to access them. But it can get the vtkMRMLLayoutNode from the scene, because if its view node’s ParentLayoutNode is nullptr (most of the cases, except when a view is shown outside of the layout) then you can look up the vtkMRMLLayoutNode by its singleton tag (`scene->GetSingletonNode("vtkMRMLLayoutNode","vtkMRMLLayoutNode")`). When you change the `MaximizedLayoutName` property then the layout manager will detect the change and act accordingly. You need to add the new `MaximizedLayoutName` property to `vtkMRMLLayoutNode`, along with `GetMaximizedLayoutName` and `SetMaximizedLayoutName` methods to get/set it.

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [June 12, 2021, 12:06pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/8 "2021-06-12T12:06:04Z")

</div>

I see that you marked the above answer as Stilton. Did this mean that you are going to implement the temporary maximize/restore view feature or you just switch layouts?

---

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [June 12, 2021, 12:13pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/9 "2021-06-12T12:13:07Z")

</div>

I already implemented maximizing/minimizing feature but by using switching layouts

code for 3D Layout:

```auto
    int layout_3D = vtkMRMLLayoutNode::SlicerLayoutOneUp3DView;
    int layout_FourUp = vtkMRMLLayoutNode::SlicerLayoutFourUpView;
    vtkMRMLLayoutNode* layoutNode = vtkMRMLLayoutNode::SafeDownCast(this->mrmlScene()->GetSingletonNode("vtkMRMLLayoutNode", "vtkMRMLLayoutNode"));
    if (layoutNode)
    {
        if (!maximumView_ThreeDView) {
            layoutNode->SetViewArrangement(layout_3D);
            maximumView_ThreeDView = true;
            d->actionCenter->setToolTip("Minimize");
        }
        else {
            layoutNode->SetViewArrangement(layout_FourUp);
            maximumView_ThreeDView = false;
            d->actionCenter->setToolTip("Maximize");
        }
    }

```

code for Axial, sagittal, cornal:

```auto
    QString x = d->ViewLabel->text();
    int layout = vtkMRMLLayoutNode::SlicerLayoutFourUpView;
    int layout_Red = vtkMRMLLayoutNode::SlicerLayoutOneUpRedSliceView;
    int layout_Yellow = vtkMRMLLayoutNode::SlicerLayoutOneUpYellowSliceView;
    int layout_Green = vtkMRMLLayoutNode::SlicerLayoutOneUpGreenSliceView;

    vtkMRMLLayoutNode* layoutNode = vtkMRMLLayoutNode::SafeDownCast(this->mrmlScene()->GetSingletonNode("vtkMRMLLayoutNode", "vtkMRMLLayoutNode"));
    if (layoutNode) {
        if (x.contains("R")) {
            if (!maximumView) {
                layoutNode->SetViewArrangement(layout_Red);
                maximumView = true;
                d->actionFit_to_window->setToolTip("Minimize");
            }
            else
            {
                layoutNode->SetViewArrangement(layout);
                maximumView = false;
                d->actionFit_to_window->setToolTip("Maximize");
            }
        }
        else if (x.contains("G")) {
            if (!maximumView) {
                layoutNode->SetViewArrangement(layout_Green);
                maximumView = true;
                d->actionFit_to_window->setToolTip("Minimize");
            }
            else
            {
                layoutNode->SetViewArrangement(layout);
                maximumView = false;
                d->actionFit_to_window->setToolTip("Maximize");
            }
        }
        else if (x.contains("Y")) {
            if (!maximumView) {
                layoutNode->SetViewArrangement(layout_Yellow);
                maximumView = true;
                d->actionFit_to_window->setToolTip("Minimize");
            }
            else
            {
                layoutNode->SetViewArrangement(layout);
                maximumView = false;
                d->actionFit_to_window->setToolTip("Maximize");
            }
        }
    }

```

And this method works, but please let me know if this is the right way to do or not.

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [June 12, 2021, 1:15pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/10 "2021-06-12T13:15:37Z")

</div>

Thank you for sharing. This can work for a custom application where to have full control over what view layouts you allow your user to choose. However, this is not a general solution that could be used in Slicer core for several reasons. For example, there is no one-up layout for every view.

---

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [June 12, 2021, 3:28pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/11 "2021-06-12T15:28:35Z")

</div>

For implementing “temporary maximize/restore view feature”

```auto
void vtkMRMLLayoutNode::SetMaximizedLayoutName(const char *MaximizedLayoutName)
{
  //do something
}

const char *vtkMRMLLayoutNode::GetMaximizedLayoutName()
{
  //do something
}

```

After this I am unable to proceed.

---

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [June 12, 2021, 8:09pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/12 "2021-06-12T20:09:06Z")

</div>

Basically I am not able figure out how to notify `qMRMLLayoutManager` to change the layout.

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [July 21, 2021, 1:38am UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/13 "2021-07-21T01:38:48Z")

</div>

Were you able to solve this or you have given up on this? Let us know if you are still interested in implementing this and need help.

---

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [July 21, 2021, 2:35am UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/14 "2021-07-21T02:35:21Z")

</div>

Yes, I am still interested in implementing this, but need some help.

For implementing “temporary maximize/restore view feature”

```auto
void vtkMRMLLayoutNode::SetMaximizedLayoutName(const char *MaximizedLayoutName)
{
  //do something
}

const char *vtkMRMLLayoutNode::GetMaximizedLayoutName()
{
  //do something
}

```

After this, I am unable to proceed.

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [July 21, 2021, 12:11pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/15 "2021-07-21T12:11:01Z")

</div>

In these methods you would just store the name of the layout. Note that the “layout” word can unfortunately used for two different things: A. name of a view arrangement, B. name of a view within a view arrangement (LayoutName property of a view node). In this case “LayoutName” refers to B (the variable stores the name of a view).

You don’t need to write the implementation of these methods, you can just add these lines to vtkMRMLLayoutNode.h:

```auto
vtkGetStringMacro(MaximizedLayoutName);
vtkSetStringMacro(MaximizedLayoutName);

```

and create and initialize and delete the member variable:

- in the header: declare `const char* MaximizedLayoutName`
- in the constructor set `this->MaximizedLayoutName = nullptr;`
- in the destructor call `this->SetMaximizedLayoutName(nullptr);`

After this, you need to implement in layoutmanager to observe this MaximizedLayoutName property and hiding of views in CTK.

---

<div class="post-metadata">

### Author: ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)
#### Post date: [July 21, 2021, 4:32pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/16 "2021-07-21T16:32:05Z")

</div>

> [@lassoan](#):
>
> In these methods you would just store the name of the layout. Note that the “layout” word can unfortunately used for two different things: A. name of a view arrangement, B. name of a view within a view arrangement (LayoutName property of a view node). In this case “LayoutName” refers to B (the variable stores the name of a view).

Would it make sense to add an entry to the [glossary](https://slicer.readthedocs.io/en/latest/user_guide/getting_started.html#glossary) ?

---

<div class="post-metadata">

### Author: ![trash\_imp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/trash_imp/32/11178_2.png) [@trash\_imp](https://discourse.slicer.org/u/trash_imp)
#### Post date: [August 21, 2021, 4:48pm UTC](https://discourse.slicer.org/t/add-button-to-maximize-view/18092/17 "2021-08-21T16:48:58Z")

</div>

I’m sorry for the late reply, but I would like to complete this “Add button to maximize view” functionality.

- I’ve completed adding the code in `vtkMRMLLayoutNode`.
- I am not able to understand how to hide the views in CTK?

So could you please elaborate
