I am trying to create a basic map editor for fun which consists of a scrollbox and paintbox (to draw the grid).
In the OnMouseDown event for the paintbox I create images at runtime and add them inside the scrollbox, the grid paintbox is painted above the images ( because if the grid was at the back it just would not look good ).
Here is a sample screen:
My question would solve two of my problems in one.
I need to be able to drag and drop (to move) the images around at runtime.
I also need to be able to get the X and Y position of the image to display as information.
Here is where my problem lies, to solve the problems above I first need to get the Image under the mouse cursor. But because I paint my grid (paintbox) above the images, the cursor will only ever 'see' the paintbox grid, and not the underlying images.
I did experiment with copying the paintbox grid to a TImage but it came out all wrong and I was getting out of memory errors. The size of the maps could be quite large and so putting the grid onto a bitmap is not ideal due the memory and limitations etc.
The grid must go on the top, otherwise it would look something like this:
Which hides the grid, and I don't want that to happen.
So, how can I see past the paintbox and get to the images underneath, using FindVCLWindow or something similar?
Set the Enabled property of the PaintBox to False. That will let the mouse messages go through.
Further:
In the OnMouseDown event for the PaintBox I create images at runtime and add them inside the scrollbox
Change that to the OnMouseDown event on the ScrollBox. Adjust the coordinates by ScrollBox.[Horz/Vert]Scrollbar.Position.
Related
I'm trying to make an editor using Konva.js.
In the editor I show a smaller draw area which becomes the final image. For this I'm using a group with a clipFunc. This gives a better UX since the transform controls of the transformer can be used "outside" of the canvas (visible part for the user) and allow the user to zoom and drag the draw area around (imagine a frame in Figma).
I want to implement object snapping based on this: https://konvajs.org/docs/sandbox/Objects_Snapping.html. (just edges and center for now) However I want it to be able to work when having multiple elements selected in my Transformer.
The strategy I'm using is basically calculating the snapping based on the .back element created by the transformer. When I know how much to snap I apply it to every node within the transformer.
However when doing it, the items starts jittering when moving the cursor close to the snapping lines.
My previous implementation was having the draw area fill the entire Stage, which I did manage to get working with the same strategy. (no jitter)
I don't really know what the issue is and I hope some of you guys can point me in the right direction.
I created a codepen to illustrate my issue: https://codesandbox.io/s/konva-transformer-snapping-1vwjc2?file=/src/index.ts
If I create a Multi-Device application in Delphi 10 Seattle (no controls on the form), run the app., and resize the form to make it larger, I see a hint of a black background rectangle following my cursor and every so often the form jumps to the new position indicated by the black rectangle.
With a form loaded with many controls, the black background rectangle is much more pronounced (extending far outside the edges of the form especially if I drag the cursor fast) and there is a very noticeable delay before the form jumps to each new position. The enlargement of the form appears to take place in a series of big jumps. To my eyes, this is ugly. Is there any way to have the form enlarge smoothly rather than in this jerky fashion?
PS I just noticed this only occurs when compiled for Windows. Compiled for OS X, the form does enlarge smoothly.
How can change alphablend of a form without affect on control in form?
Delphi XE7
One solution to this problem is to use Multi-Device Application (if using VCL is not possible).
If you need to leave a transparent TForm just changing a property Transparency = True.
If you need to leave a semi-transparent component, all components have the Opacity property that can be assigned a more transparent value between 0 and 1, where 0 is closer to that component.
For example you could put the controls within a TLayout and change the Opacity of it as you see fit, and have no effect on the other components, or vice versa.
Actually the answer to this might be pretty simple...(for windows only)
The JEDI VCL library has a component (TJvTransparentForm) that allows you to take an Alpha blended PNG image (ie the gray background shown in your picture above) and use it to make a form control. The picture is actually stored in a TImage and you would need to place your "Icons" on the image itself. Then just respond to the mouse clicks on the TImage.
You have what your asking for (maybe?).
If you were tricky enough you could probably even track the mouse movement and change the Image to glow the correct "button" that the mouse was over.
In my FMX Application I have to fill the entire background area of my form using a Bitmap pattern.
The reason why I'm thinking to use this pattern is because the form is freely resizable by the user and whether I set a fixed image the stretch causes the loss of quality of the background.
Is there a way to use a small Bitmap pattern I can repeat (X and Y) to fill the whole form area according to the resizing?
The effect you are looking for is a Tile.
See TTilerEffect and FireMonkey_Image_Effects for documentation.
The properties HorizontalTileCount and VerticalTileCount controls how many times a bitmap will be replicated. Since these values are floats, you need to adapt their values when the form is rescaled.
Add a TImage to the form
Make all the other controls children of it (so they appear on top).
Set the image's Align to alClient.
Load the Bitmap.
Set the WrapMode to imTile.
I have a Image list assigned to a listview to display transparent images.
There is a slight issue with this regarding some transparent images that are added, and that is they are sometimes hard to see/find in the listview.
See this example image:
You will notice that the images (noticeably the mouse) is barely viewable, infact if a empty image was added you would not even see it, the number captions come to the rescue here to show there is something actually there.
But I would like to make the images visually easier to see. I thought maybe having another image underneath the transparent images would work - of course though it could not affect the actual image.
So with that in mind, I made a bitmap of a chessboard grid:
I feel this would be the most suitable way of representing transparent areas of the images just like Paint.NET etc does.
To further illustrate this example I have modified the original image to show how it would look, if we had the chessboard bitmap as the underlay image:
Having the chessboard there would indicate there is a list item there in the first place, and the bitmap of the chessboard grid could be darker or an altogether different kind of image. As I said earlier if there was no image you would see nothing at all, so better to show an empty chess grid or other bitmap than nothing.
So, how can I display a second image underneath the original images using a imagelist to give a result similar to the example above? The underneath image could be anything - just another loaded bitmap for example.
If you store the chessboard as the first image (with index 0) and make the overlay image from the current image in the OnGetImageIndex event handler, it will do what you want to. However I'm not sure how efficient is to make the overlay image every time the event is fired.
procedure TForm1.ListView1GetImageIndex(Sender: TObject; Item: TListItem);
begin
// make the overlay (with overlay index 1) from the
// image with index Item.Index + 1
ImageList1.Overlay(Item.Index + 1, 1);
// use the first image from the list as a background
Item.ImageIndex := 0;
// and assign just created overlay index for overlay
Item.OverlayIndex := 1;
end;
I seems that what you need is a TImageList with extra capabilities.
As a starting point, I suggests you to consider TImageListEx described in the book Inside Delphi 2006
Excerpt:
The TImageListEx component is a TImageList descendant that can use the
images from another image list to generate disabled images, which can
be used on toolbars and other user interface elements.
The TImageListEx component is a TImageList descendant that can use the
images from another image list to generate disabled images, which can
be used on toolbars and other user interface elements.
There are several benefits of the TImageListEx component:
It eliminates the need for creating disabled glyphs.
It eliminates the need for adding the disabled glyphs to an additional TImageList component at design time.
It can drastically reduce the size of the .dfm file and of the entire application, especially in large applications that use a lot of
glyphs.
It's extremely fast, taking only milliseconds to disable all images in an image list, even when there are number of images.
It's extremely lightweight. (If you add it to an application that already uses the standard TImageList component, it won't increase the
size of the executable at all, and if you add it to an application
that doesn't use the standard TImageList component, the overhead is
only 2 KB.)
It's far from your requirements but yet detailed enough to show how to extend TImageList.