Morphic: Automatically resize contained group box in a scroll pane?

684 views Asked by At

Testing with Pharo 1.4 summer. I think is better to explain it using screenshots, code is below.

This is my initial state (what I'm getting now with my code):

Initial State

I want the group box morph to be filled horizontally on opening, like this:

Initial Desired State

And after resizing, I want the group box morph to maintain the bounds, i.e.:

Resize Desired State

This is the code I've tried:

| s morph1 morph2 row groupBox scroller |
s := ScrollPane new.
morph1 := BorderedMorph new.
morph2 := BorderedMorph new.
row := UITheme builder newRow: {morph1 . morph2}.
groupBox := UITheme builder newGroupbox: 'Group Box Test' for: row.
    groupBox 
        layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 0.8));
        vResizing: #spaceFill;
        hResizing: #spaceFill;
        layoutChanged.
scroller := s scroller.
scroller 
    addMorph: (groupBox position: 0@0)
    fullFrame: (0 @ 0 corner: [email protected]).
s scroller color: Color white.
s
 extent: 250@150;
 openCenteredInWorld

The container must be a ScrollPane.

I have adapted the code of Bert to not to use the Polymorph UIBuilder, resulting in:

morph1 := Morph new.
morph2 := Morph new.
row := ScrollPane new.
row
    color: Color white; borderColor: Color gray; borderWidth: 1;
    layoutPolicy: ProportionalLayout new.
row scroller
    addMorph: morph1 fullFrame: (LayoutFrame fractions: (0@0 corner: 1@0) offsets: (5@5 corner: -60@45));
    addMorph: morph2 fullFrame: (LayoutFrame fractions: (1@0 corner: 1@0) offsets: (-50@5 corner: -5@45)).
row
    extent: 250@150;
    openInHand

but also doesn't work because the inner blue morphs are overlapped and not filling the specified frame. I tried many combinations using frames but nothing worked so far. Do you know what I'm missing?

2

There are 2 answers

0
Hernán On BEST ANSWER

Using UIBuilder you don't need to create manually a scroller. Check the following script by resizing until vertical or horizontal scroll bars appear automatically.

| dialog morphList row morph1 morph2 morph3 morph4 |

morph1 := BorderedMorph new hResizing: #spaceFill.
morph2 := BorderedMorph new.
morph3 := BorderedMorph new.
morph4 := BorderedMorph new.
row := UITheme builder newRow: {morph1 . morph2 . morph3}.
morphList := UITheme builder 
    newMorphListFor: (ListModel new list: {row . morph4})
    list: #list 
    getSelected: #selectionIndex 
    setSelected: #selectionIndex:
    help: 'This is a morph list'.
dialog := UITheme builder newWindowFor: nil title: 'titleString'.
dialog addMorph: morphList fullFrame: (LayoutFrame fractions: (0@0 corner: [email protected])).
dialog openInWorld
1
codefrau On

You're missing that ProportionalLayout does not use #spaceFill etc. So either use TableLayout:

morph1 := Morph new hResizing: #spaceFill.
morph2 := Morph new.
row := Morph new
    color: Color white; borderColor: Color gray; borderWidth: 1;
    layoutPolicy: TableLayout new;
    layoutInset: 5; cellInset: 5;
    listDirection: #leftToRight;
    addAllMorphs: {morph1. morph2};
    extent: 250@150;
    openInHand

or a ProportionalLayout with offsets, which is how you can mix fixed-width and relative dimensions:

morph1 := Morph new.
morph2 := Morph new.
row := Morph new
    color: Color white; borderColor: Color gray; borderWidth: 1;
    layoutPolicy: ProportionalLayout new;
    addMorph: morph1 fullFrame: (LayoutFrame fractions: (0@0 corner: 1@0) offsets: (5@5 corner: -60@45));
    addMorph: morph2 fullFrame: (LayoutFrame fractions: (1@0 corner: 1@0) offsets: (-50@5 corner: -5@45));
    extent: 250@150;
    openInHand

I tried this in Squeak which does not have UITheme, so this is using Morphs directly.