pharo-graphics / Bloc

Low-level UI infrastructure & framework for Pharo
MIT License
80 stars 39 forks source link

ProportionalLayout: need to add an offset constraint (L B R T) complementary to proportional constraint #562

Closed labordep closed 2 weeks ago

labordep commented 1 month ago

Hi,

The need is to define a pixel offset value (for each directions : left, bottom, right, top). This value should be negative (for example: -5px).

Illustration with a concrete use case: image

Note: dimensions of this picture are not representative.

Thanks :)

Nyan11 commented 1 month ago

Could use the the margins, but it does not seem to work.

Here i added a margin of 10px to all children. See:

BlElement new
   constraintsDo: [:constraints |  constraints horizontal exact: 400.0.
      constraints vertical exact: 300.0 ];
   id: #A;
   layout: BlProportionalLayout new;
   addChildren: {(BlElement new
         constraintsDo: [:constraints |  constraints proportional vertical bottom: 0.5.
            constraints margin: (BlInsets all: 10.0) ];
         id: #B;
         background: (BlPaintBackground new
               paint: (BlColorPaint new
                     color: (Color r: 0.9413489736070382 g: 0.05865102639296188 b: 0.0 alpha: 1.0);
                     yourself);
               opacity: 1.0;
               yourself);
         border: (BlBorderBuilder new
               paint: (BlColorPaint new
                     color: (Color r: 0.0 g: 0.0 b: 0.0 alpha: 1.0);
                     yourself);
               build);
         yourself) . 
      (BlElement new
         constraintsDo: [:constraints |  constraints proportional horizontal right: 0.5.
            constraints proportional vertical top: 0.5.
            constraints margin: (BlInsets all: 10.0) ];
         id: #C;
         background: (BlPaintBackground new
               paint: (BlColorPaint new
                     color: (Color r: 0.0 g: 0.0 b: 1.0 alpha: 1.0);
                     yourself);
               opacity: 1.0;
               yourself);
         border: (BlBorderBuilder new
               paint: (BlColorPaint new
                     color: (Color r: 0.0 g: 0.0 b: 0.0 alpha: 1.0);
                     yourself);
               build);
         yourself) . 
      (BlElement new
         constraintsDo: [:constraints |  constraints proportional horizontal left: 0.5.
            constraints proportional vertical top: 0.5.
            constraints margin: (BlInsets all: 10.0) ];
         id: #D;
         background: (BlPaintBackground new
               paint: (BlColorPaint new
                     color: (Color r: 0.0 g: 0.0 b: 1.0 alpha: 1.0);
                     yourself);
               opacity: 1.0;
               yourself);
         border: (BlBorderBuilder new
               paint: (BlColorPaint new
                     color: (Color r: 0.0 g: 0.0 b: 0.0 alpha: 1.0);
                     yourself);
               build);
         yourself)};
   background: (BlPaintBackground new
         paint: (BlColorPaint new
               color: (Color r: 0.5 g: 0.5 b: 0.5 alpha: 1.0);
               yourself);
         opacity: 1.0;
         yourself);
   yourself

image

The gap between the parent border and the child is correct but the gap between the children are not.

tinchodias commented 1 month ago

I see the point, and I'm doing a PR to evaluate. I wrote current math calculations of this layout taking the inspiration on the Morphic proportional and AFAIU it was like it is now. But I see your point, the offset of the children's margin would be very convenient in the way you request.

ELePors commented 1 month ago

In my opinion margin are not a solution for this problem. I just want to personalize the proportion... I prefer to access to topOffset than using margin top ...

too objects to do the job kill the solution... i prefer to use a single object for constraints ... BlInsets all ... lets keep api simple to use... we don't have to know Bloc elements to manipulate bloc... (i have the same remark about : visbility ... )

Cheers ! :)

Eric

tinchodias commented 1 month ago

Okay, I see. However, as it is right now, all BlElement have padding and margin and they are stored internally in a layout constraint inst var. When the parent has a proportional layout, the children's margin is ignored if we store this as another inst var.

See in BlElement:

padding: aBlInsets
    self padding = aBlInsets ifTrue: [ ^ self ].
    self constraintsDo: [ :c | c padding: aBlInsets ]

and

margin: aBlInsets
    self margin = aBlInsets ifTrue: [ ^ self ].
    self constraintsDo: [ :c | c margin: aBlInsets ]
tinchodias commented 1 month ago

In grid layout, the margin of the children has a similar effect in the rendering: a gap between the "cells":

gap := 5.

cell1 := BlElement new
             background: Color red;
             constraintsDo: [ :c |
                 c horizontal matchParent.
                 c vertical matchParent.
                 c margin: (BlInsets all: gap) ];
             yourself.

cell2 := BlElement new
             background: Color green;
             constraintsDo: [ :c |
                 c horizontal matchParent.
                 c grid horizontal weight: 3.
                 c vertical matchParent.
                 c margin: (BlInsets all: gap) ];
             yourself.

container := BlElement new
                 background: Color blue;
                 layout: (BlGridLayout new columnCount: 2);
                 size: 100 @ 100;
                 addChild: cell1;
                 addChild: cell2;
                 yourself.

container exportAsPNG

gap := 5: BlElement-881684224

gap := 0: BlElement-921712384

gsp := 10: BlElement-219631872