Changing control's z-order

If someone gets time to try that, it’d be nice to know and may prove to be useful.

The technique of drawing all on one canvas is still better, but you can emulate part of it.
Instead of detecting mouse events on the canvases, dont handle them there, but let the containing window do it.

eg with no mouse events on the canvases, add this code to the window mousedown handler


dim probablecanvas as canvas 
//probablecanvas is defined here for explanation
//I would normally make it a property of the window

probablecanvas = nil

for each c as control in self.Controls
  if c isa canvas then
    
    //this stuff could also be tested using Contains()
    if probablecanvas = nil and x > = c.left and x <= c.left + c.width then
      if y > = c.top and x <= c.top + c.height then
        probablecanvas = c
      end if
    end if
    
  end if
  
next

if probablecanvas <> nil then
  // now do something because we have identified 
  // a canvas.
  // maybe select it and repaint?
  //if probablecanvas is a property of the window,
  //you could use it in the window mousemove/mousedrag events
  //which follow
  
end if

at the end of this, probablecanvas ‘knows’ which canvas you clicked upon.
in other window mouse events, you can move the canvas about, without losing mouse events.

I can give it a go, any particular control(s) you want to try?

I like this option. I’ll try it out and let you know.

nb: there is a typo

if y >= c.top and x <= c.top + c.height then

should be

if y >= c.top and y <= c.top + c.height then

Thanks.
I think a checkbox and a listbox would be a good test (the checkbox being a simple, yet native control, while the listbox is the opposite).

Hi Jeff, I changed the code a little and it works perfectly well until the point where I change the z-order. Closing the canvas seems to not trigger the MouseDrag event. Is it possible to change the z-order outside the MouseDown event?

Window1.MouseDown:

for each obj as Object in self.Controls
  if obj isA DesktopCanvas then
    var thisCanvas as DesktopCanvas = DesktopCanvas(obj)
    if canvasSelected = nil and x >= thisCanvas.Left and x <= thisCanvas.Left + thisCanvas.Width then
      if y >= thisCanvas.Top and y <= thisCanvas.Top + thisCanvas.Height then
        canvasSelected = thisCanvas
        canvasSelected.Close
        self.AddControl(canvasSelected)
        Exit for 
      end if
    end if
  end if
next
return true

Window1.MouseDrag

if canvasSelected <> nil then
  canvasSelected.Left = x - (canvasSelected.Width / 2)
  canvasSelected.Top = y - (canvasSelected.Height / 2)
end if

Window1.MouseUp

canvasSelected = nil

1 Like

return true at the end should make the mousedrag event fire.

Edit: just tried it, and no, it didnt fire

Z-order re-ordering works with both DesktopCheckBox and DesktopListBox on Mac, I haven’t tried Windows, not sure if it’ll make a difference.

The left-most checkbox was created first and was at back of display then in the above image after re-ordering. Same with the listbox. I hope that helps.

But do those controls retain their state - ie, does the checkbox stay checked? Does the listbox retain its rows?

1 Like

In both, it retained the properties I changed. The ListBox loses selected row. Here’s before and after re-ordering images.


In both, it retained the properties I changed. The ListBox loses selected row.

Thanks for having tried.
Things like the listbox losing its selection makes the procedure incertain; when using that trick, you’d better know in advance what you should restore in code to avoid the user losing information.

I haven’t read this thread in depth, but doesn’t DragItem.DragPicture do what you need?