Recent

Author Topic: Container with transparent background, or TShape/TImage on top of everything  (Read 850 times)

kinnon_2000

  • New Member
  • *
  • Posts: 22
Hello,

I've been puzzling over this for a few days now.
I'm building a menu system with drag-drop controls.
I have a stack of TFrameMenuIts in a TFrameContainer.

When I drag a menu item, I indicate the nearest drop location with a control containing an image or shape.

Because of all the frames, which are container objects I can't just position a shape because it won't be on top of them, so not visible.

I have to put the drop marker in a container. I tried a TPanel, but couldn't easily get rid of the background rectangle, so tried making a frame to contain it and so far same problem.

I've attached a screenshot to help illustrate what I'm doing. The mad colours in the demo are just to make it easier for me to debug the behaviour.
In the example, I'm using a BGRAShape in a frame called FrmMarker.

I also tried making a BGRAPanel transparent as the container of my shape but wasn't successful. If this can be done this way, any advice on how to achieve it?

I have seen similar questions which either wouldn't work with multiple components below the marker container, or involve creating a new component myself, which I would rather avoid and would slow me down a lot.

Ideally, I would need a panel with no borders and with alpha blend value or transparency which works.
Seems like a tricky thing to do considering such wide application potential.   

Any suggestions would be greatly appreciated

All the best,
Al.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
I am unsure if it helps: BGRAVirtualScreen.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

jamie

  • Hero Member
  • *****
  • Posts: 6791
in the examples folder of the lazarus install there is a "DragImageList" project. That can give you an idea of what can be done that is already built in.

 Also, most of the controls that I know of have a drag and drop operation.
The only true wisdom is knowing you know nothing

kinnon_2000

  • New Member
  • *
  • Posts: 22
Thanks for the responses.

Jamie, drag-drop operations aren't a problem for me but thanks for the recommendation.

BGRAVirtualScreen looks like it has potential although I'm struggling with it.
I do not see any examples where transparency works outside of its own container scope after digging around the tutorials (https://wiki.freepascal.org/BGRABitmap) and this forum as well as general web searches.

I've made a little demo to try and get a proof of concept working.
The screenshot below illustrates what I have so far and what I would like to achieve.
I've attached the project files.

The only code is as follows:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.VsRedraw(Sender: TObject; Bitmap: TBGRABitmap);
  2. begin
  3.      Vs.Bitmap.Rectangle(20, 20, Vs.Width-20, Vs.Height-20, BGRABlack, BGRA(0, 0, 0, 100), dmDrawWithTransparency);
  4.      Vs.Bitmap.EllipseAntialias(0,0,20,30,BGRABlack,1, BGRA(0, 0, 0, 100));
  5. end;
  6.  


Any suggestions? I'm starting to think this is not possible.

Regards,
Al

kinnon_2000

  • New Member
  • *
  • Posts: 22
SUCCESS!! Whoop

So, I figured out a very simple solution after discovering TCustomForm.GetFormImage to capture an image of the form underneath my pMarker panel, and pMarker.canvas.BrushCopy to draw this rect image into a regular panel.
https://lazarus-ccr.sourceforge.io/docs/lcl/forms/tcustomform.getformimage.html.

the pMarker panel seems to be included in the copy operation as if it is underneath everything else instead of on top (not an issue for me).

Another basic demo image is attached with the before and after. Also tested after putting a pile of other components in the panels and it still works.

For anyone interested, here's the code I use to test it, within an on click event for the pMarker panel I'm drawing on:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.pMarkerClick(Sender: TObject);
  2. var r:TRect;
  3. begin
  4.   r:=pMarker.Canvas.ClipRect;
  5.   r.Left:=pMarker.Left;
  6.   r.Top:=pMarker.Top;
  7.   r.Right:=r.Right+r.left;
  8.   r.Bottom:=r.Bottom+r.Top;
  9.   // copy an image of whats under this panel
  10.   pMarker.Canvas.BrushCopy(pMarker.Canvas.ClipRect, Form1.GetFormImage, r, clgreen);
  11.   // draw a shape on the canvas now that it contains a copy of whats under it
  12.   pMarker.Canvas.brush.Color:=clBlack;
  13.   pMarker.Canvas.Polygon([Point(0,0), point(pMarker.Width,0), point(pMarker.width div 2,pMarker.Height)]);
  14. end;
  15.  




 

TinyPortal © 2005-2018