spirali / nelsie

Framework for Creating Slides
MIT License
39 stars 4 forks source link

Grid Layout for Images - Box size inheritance not working? #46

Open ravenswing opened 2 months ago

ravenswing commented 2 months ago

Hi, I am trying to produce something like the attached image (Fig. 1) essentially a slide with a 3x3 grid of images, with a title. I say this in case there is a much easier way to obtain this layout, and the issue I am experiencing is not an issue at all!

As a test, I am trying to create a 2x2 grid, using nested boxes:

@deck.slide() 
def test(slide): 
  row1 = slide.box(row=True) 
  row2 = slide.box(row=True) 
  row1.image("image/path.png") 
  row1.image("image/path.png")
  row2.image("image/path.png") 
  row2.image("image/path.png")

This produces the output in Fig. 2, where the images are aligned in a grid but only a small portion is showing.

If I try to fix the heights, even very small ones, the images overlap as seen in Fig. 3.

@deck.slide() 
def test(slide): 
  row1 = slide.box(row=True, height=100) 
  row2 = slide.box(row=True, height=100) 
  row1.image("image/path.png") 
  row1.image("image/path.png")
  row2.image("image/path.png") 
  row2.image("image/path.png")

If I individually set the height and width to "50%" for all the .image() lines, then the slide is completely blank!

My questions are:

  1. Is there an easier way to do this that I am missing?
  2. Within the current boxes-within-boxes setup, how do I get it so that the images are all arranged evenly on the slide, or is there an error somewhere like the child boxes are not properly inheriting the total size from the parent?
  3. In the future, is there the possibility of having a set grid layout e.g. akin to matplotlib's subplot where you can create and populate a grid of boxes?

Fig. 1 - Intended Output: example

Fig. 2 - Slide without heights specified: image

Fig. 3 - Slide with heights specified: image

spirali commented 2 months ago

Thank you for your report. I will look at it. At the first sight it seems as some problem in the layouting library.

So far, there is no easier way (hmm, maybe you can play with flex_wrap so you can put everything in one box).

Taffy, the layouting library used in Nelsie supports also a grid layout, but it is not exposed to Nelsie API now. But it should be quite straightforward to implement it, I just did not have a use case for it. I am putting it on my roadmap.

Sorry for late response. I totally overlooked this issue.

spirali commented 2 months ago

Can you please send me your image so I can replicate the problem exactly? (or just sizes of your image)

One option for your problem can be set the sizes not to the row box but the images itself: row1.image("image/path.png", height=100)

ravenswing commented 2 months ago

Thank you so much for looking into this! I have tried a few more things, and although I know too little Rust to help fix it, I thought any info might help narrow down the issue:

I don't know if this is related, but I have also noticed that reducing/changing the pixel width & height in the SlideDeck() initialisation does not change the filesize of the output pdf at all. I don't know whether that is expected, but to me that seems odd!

I have attached an example image I am using as you said, and thanks again for actively developing such a cool tool! slides_test

spirali commented 1 month ago

Hi, thank you for the image. You can do it as follows:

@deck.slide() 
def test(slide): 
  row1 = slide.box(row=True, height="50%") 
  row2 = slide.box(row=True, height="50%") 
  row1.image(path="test.png", height="100%") 
  row1.image(path="test.png", height="100%")
  row2.image(path="test.png", height="100%") 
  row2.image(path="test.png", height="100%")

The reason is that box always tries to be as small as possible, so we have to first set heights to rows (as height in pixels, or percent from parent). Otherwise it will happily occupy 0px height and images will just take a portion of this 0 if their height is specified in %. (Note that the top level box is special and it has a fixed size, so it cannot collapse to zero).

PDF size is not changed because PDF is a vector format. If you embed a raster image then it is saved in the original resolution.

spirali commented 1 month ago

Btw: Your problem is similar to the #11 where I tried to explain it with more examples.