Advice for a design to display stamp images in a window

Hi,

I’ve made the screen shot below to display how useless the sort of objects (here Canvas) is in Xojo IDE, but it goes fine too for my question.

In a window, I put a bunch of Canvas (8 in a Row) to be container of stamps images (128 pixels high, width is variable).

I added an images FileType Set (FT_Imgs),
I subclassed the Canvas Control, add code to Open and DropObject, set these Canvas supper to this subclass, and check if these works fine.
Then, I added code to shrink horizontally the Canvas to only fits the dropped image and this works fine.

When it comes to move the Canvas to stick to its left neightbor, I… after some minutes I realized that I have no idea to how to do that.

Also, it may not be a good idea to have so many Canvases in the window.

At this stage, I am here asking you for advices (after an evening and a night: nothing comes to me at woke up time, nor 'till now).

Why don’t you use a Control set for all these canvases ? You could fold them into one not to clutter the IDE. And addressing them with index would probably be a whole lot easier.

Hi Michel,

Thank you for your answer: I will follow it in the afternoon.

And you are right for the number of Controls: I do not liked that at all…

You’re welcome.

To make all the canvases part of the same control set, select them all, then in the gear Inspector, select “New Control set”.

Emile, you may also want to consider using Container Controls. In the Container Control, you can add a Canvas Control as well as Properties related to the Image. These could then be part of the same Control Set. Here is a link to an excellent BKeeney blog post on Container Controls: http://www.bkeeneybriefs.com/2014/02/container-control-love/

@Thomas:

I never used Container controls (as you may feel) because I never understand its usage / how good it can be for me.

I read the shared link, but I have to read it once more with “Open Mind” and no disturbance around me ;-:).

Thanks for the advice.

If you mean to stick to the left at run time, this works for 20 canvas in a control set. See how easy it is as opposed to setting left and right for 20 separate Canvas :

Sub Action() dim currentcanvas as integer dim gauche as integer = 100 dim haut as integer = 100 For row as integer = 0 to 3 For column as integer = 0 to 4 Canvas1(column+(row*5)).Top = haut+Canvas1(0).Height*row Canvas1(column+(row*5)).Left = gauche+column*Canvas1(0).Width next column next row End Sub

If you mean at design time, simple arithmetics give you left and top.

You may think of a Container control as a window that you can stick inside another (it is exactly that), so you can place all the canvases on one, and then place all of them at once on a window. Convenient if you want to move them all as a block at run time.

You are far from having the maximum. There are applications around that use hundreds !

One detail I may forgot: the loaded images share the same height, but have (or can have) different widths. That is why I want to change the Canvas location dynamically. I may eventually have to modify a bit the window width (I do not have a real constraint for the window width: I can display 8, 9, 10 images a Row…).

Thanks for your advices.

You posted a picture with squares. Difficult to guess you wanted variable width.

This can still be achieved by modifying the code I posted, but you will have to add all previous canvas width in the row instead of simply multiplying.

What you want to do would be very simple with Auto Layout, but it is not available yet in Desktop.

Or you might want to use ONE and only ONE canvas, and keep your images in an array or dictionary

In the PAINT event, just loop thru the array and use DRAWPICTURE to place each image where you want them. This also reduces your paint event requirements… and increases the flexibilty for future enhancements

Sub Paint()
  dim currentcanvas as integer
  dim gauche as integer = 100
  dim haut as integer = 100
dim index as integer
  For row as integer = 0 to 3
    For column as integer = 0 to 4
index=column+(row*5)
g.drawpicture image(index),haut+image(index).Height*row,gauche+image(index).width*column
    
    next column
  next row
End Sub

I would recommend using a ContainerControl as a parent layout object that manages embedded containers. The nice thing about using containers is that you can instanciate and embed new ones at runtime and they can handle their own mouse events.

The image subContainers could have a constructor that accepts a picture and sets that container’s width/height, then the parent can lay them out in rows until the max width is reached, then start a new row. (And enable a scrollbar if needed)

Keep the layout code separate from the add/remove picture code and you can rerun it whenever the list of pictures changes or the parent container resizes.

You can get to the desired outcome very quickly, and have reusable objects for some point in the future when you want to do something similar (or move the view to a different window etc).

I threw together a simple example… only took about 20 minutes and I needed a diversion while the laundry runs :wink:
Run the project and drop image files in the window. Should lay them out nicely.

ImageLayout.xojo_binary_project

Thank you all for the advices / suggestions.

At last, I found this conversation. IAfter seeking for it for 15 minutes or so, I started another conversation with details on how I finally do the job].

In short:
a. the specifications was wrong (wrong design),
b. the target result is a mosaic
c. Dave: your suggestion would have been very helpful (and still may be if I have to do that in the future) if only I found this conversation earlier.

I went near Dave suggestion: I draw all small images into a single offscreen Picture that I display in one larger Canvas and my mosaic of images was done.
Only other addition was code to save the result image.

Jim: I will check your project. I do not know how many times (in real coding time) it tooks me, but once the correct design for my need was in mind, it was nearly fast to implement. The only thing that took time was figuring how DragItem.NextItem works (and before that this is the instruction to use…).

This simple utilitystarted on wrong specification just like if the order giver was a newbie ;-:slight_smile: just like if I do not knew what I wanted to get !

[quote=192587:@jim mckay]I threw together a simple example… only took about 20 minutes and I needed a diversion while the laundry runs :wink:
Run the project and drop image files in the window. Should lay them out nicely.

ImageLayout.xojo_binary_project[/quote]
FANTASTIC !

Exactly what I was asking !

Now, I have to take time to understand how it works …

PS: I put in the dropped files one that was far greater (both w and h): works fine too ! (of course).

This gives me an idea of use… this idea have to become mature… [like a green tomato, but I need it red ;-:slight_smile: ]

It should give you a good starting point. I tried to keep it simple so you could better understand how it works.

Think of a container control as a window without the frame (titlebar etc). It can have controls in it, buttons, textfields, even other containerControls. The example has a master container with a scrollbar. The image containers are added at runtime, much like you would use window.open, but containerControl.embedWithin is used.

A containerControl has to reside in a parent window/container, while a regular window resides in the desktop. They can be moved around via code within the parent window/container just like a regular window is moved via code within the desktop.

Containers are very powerful once you’ve grasped the idea :wink:

Hi Jim,

thank you for your explanation: it seem clear.

Now, I hav to put the hands in the coal to really know what it is like.

I realize the use I have for it: a master graphical “index”: each imae is a button (a launcher to something…). I already have a proof of concept project (since two or three years ago), but I never took the time to implement it (or I was unconciously not happy with it ?).