Revision history [back]

Looks like this is an open issue, opened as of two years ago with no progress: https://trac.sagemath.org/ticket/22663 (perhaps another reason there shouldn't be such a rush to deprecate SageNB, but it's a little late for that now...) Custom Jupyter Widgets do allow extensive layout customization but perhaps not in a way that's been integrated with or is fully backwards-compatible with the old Sage @interact decorator. This is because in the Jupyter notebook it's using the interact provided by ipywidgets (https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html)

It seems the easiest way to control widget layout is to manually create the individual widgets and wrap them in HBox and VBox widgets. It would also be really nice to be able to use Layout Templates though those are rather new, in the latest ipywidgets, which is not in Sage yet. So with what I have, I was able to do something I think close to what you're trying to get:

(Note: I renamed the actual function for the interact ff so I could access its widget attribute)

C:\fakepath\2019-07-11.png

Obviously this is still a bit ugly. Part of that is because I lazily re-used the widget elements that were automatically created by the original @interact call. I could either not do that and re-create the individual widgets myself. Or you an play around with adjusting their existing layout attributes. After some experimentation I wound up with

top = HBox(ff.widget.children[:2])
left = VBox(ff.widget.children[2:4])
mid = HBox([left, ff.widget.children[5]])
bottom = ff.widget.children[4]
app = VBox([top, mid, bottom])

for w in app.children:
w.layout.width = '100%'

for w in top.children:
w.layout.width = '50%'

for w in left.children:
w.layout.width='98%'

mid.children[0].width='20%'
mid.children[1].width='80%'

bottom.layout.width='99%'

app


Which gave me:

C:\fakepath\2019-07-11 (3).png

Which is a little nicer (some of the widths aren't exactly 100%, since I found that if I made it 100% my browser would add annoying scroll bars).

Alas, none of this is as nice as the old @interact(layout=...) for tutorial purposes...

Looks like this is an open issue, opened as of two years ago with no progress: https://trac.sagemath.org/ticket/22663 (perhaps another reason there shouldn't be such a rush to deprecate SageNB, but it's a little late for that now...) Custom Jupyter Widgets do allow extensive layout customization but perhaps not in a way that's been integrated with or is fully backwards-compatible with the old Sage @interact decorator. This is because in the Jupyter notebook it's using the interact provided by ipywidgets (https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html)

It seems the easiest way to control widget layout is to manually create the individual widgets and wrap them in HBox and VBox widgets. It would also be really nice to be able to use Layout Templates though those are rather new, in the latest ipywidgets, which is not in Sage yet. So with what I have, I was able to do something I think close to what you're trying to get:

(Note: I renamed the actual function for the interact ff so I could access its widget attribute)

Obviously this is still a bit ugly. Part of that is because I lazily re-used the widget elements that were automatically created by the original @interact call. I could either not do that and re-create the individual widgets myself. Or you an play around with adjusting their existing layout attributes. After some experimentation I wound up with

top = HBox(ff.widget.children[:2])
left = VBox(ff.widget.children[2:4])
mid = HBox([left, ff.widget.children[5]])
bottom = ff.widget.children[4]
app = VBox([top, mid, bottom])

for w in app.children:
w.layout.width = '100%'

for w in top.children:
w.layout.width = '50%'

for w in left.children:
w.layout.width='98%'

mid.children[0].width='20%'
mid.children[1].width='80%'

bottom.layout.width='99%'

app


Which gave me:

Which is a little nicer (some of the widths aren't exactly 100%, since I found that if I made it 100% my browser would add annoying scroll bars).

Alas, none of this is as nice as the old @interact(layout=...) for tutorial purposes...