Hi i cant figure out why this wont work.
I have a image and a selection and i want the image to always be the same size and position as the selection so i put this code in a timer:
procedure TfrmMainUI.tmrUpdateTimer(Sender: TObject);
var i : integer;
begin
Image1.Width:=Selection1.Width;
Image1.Height:=Selection1.Height;
Image1.Position.X:=Selection1.Position.X;
Image1.Position.Y:=Selection1.Position.Y;
end;
But it doesn't work.
What is supposed to happen is the image resizes to the selection and its position also follows the selection.
But what happens is that i can move and resize the selection and the image just stays where it is and doesn't resize.
As #Mike Sutton pointed out in the comments, you should be using the OnTrack event of TSelection to trigger updates to your image.
The documentation says:
The event handler of the OnTrack event is called cyclically from the
MouseMove method while the TSelection object is in the process of
moving or resizing.
Write a custom OnTrack event handler to perform a specific action when
TSelection is in the process of moving or resizing.
You state in a comment, the components are created dynamically at runtime, rather than on the designtime surface. So you will also need to assign your handler in code. Do it like this:
Selection1.OnTrack := SelectionTrack;
Your event handler will look like this:
procedure TfrmMainUI.SelectionTrack(Sender: TObject);
begin
Image1.Width:=Selection1.Width;
Image1.Height:=Selection1.Height;
Image1.Position.X:=Selection1.Position.X;
Image1.Position.Y:=Selection1.Position.Y;
end;
You also say in the comments that you need to track selection changes for a number of linked images and selections. You can modify the event handler like this:
procedure TfrmMainUI.SelectionTrack(Sender: TObject);
var
Selection: TSelection;
Image: TImage;
begin
Selection := Sender as TSelection;
Image := ImageFromSelection(Selection);//you need to implement this function
Image.Width:=Selection.Width;
Image.Height:=Selection.Height;
Image.Position.X:=Selection.Position.X;
Image.Position.Y:=Selection.Position.Y;
end;
Related
I have two canvases and two stages in CreateJS / EaselJS. The first stage has autoClear set to false and I am doing dynamic drawing on it starting with a stagemousedown event. The second stage uses nextStage to send mouse events to the first stage. The second stage has interface such as a Bitmap that I want to press on to go to another page. When I click on the Bitmap, the stage beneath does the dynamic drawing. I want the click on the Bitmap not to go through to the first stage but stopImmediatePropagation does not work, nor does putting a clone of the Bitmap with mouseEnabled false on it underneath. I can just use mousedown on the Bitmap so the user does not notice as much, but was wondering if there is a way to disable mouse events from passing through the top stage if they are acting on an object with an event set to capture? Thanks in advance.
The stagemousedown and other stage events are decoupled from the EaselJS object event model. They are catch-all events, which basically represent mouse interaction with the . Because of this, catching and stopping these events won't interrupt the display list hierarchy.
Typically if you want to block other events in the same stage, you can create a canvas-size box (Shape, etc) that will block the interaction. When dealing with nextStage, this is especially true, since we are passing on events that are unhandled by objects in the EaselJS display list.
A better approach might be to toggle the nextStage on stagemousedown, so it is null during the click event. Not sure if this will work, but its a start.
I'm doing a test VCL app with Delphi. I have an empty form with a label and i change that label value with the form FormMouseLeave event. It works, but if i keep the left mouse button pressed while leaving the form the event is not triggered.
I tried intercept the WM_MOUSELEAVE message, but looks its not triggered at all (well, i guess FormMouseLeave event is based on that message)
I don't need to trigger any drag drop, i just need my event when the mouse leave my form with left click pressed, how i can do that?
This is known behavior of WM_MOUSELEAVE message. You can circumvent it by tracking mouse movement and when mouse leaves form bounds you can trigger event yourself.
When you have mouse button down, then your window (form) has captured the mouse and will receive WM_MOUSEMOVE events even when mouse is out of it's bounds. WM_MOUSELEAVE message is meant for tracking mouse inside your window when you don't have mouse captured.
If you assign MouseEnter, MouseLeave and MouseMove events to your form you can do something like following:
procedure TForm1.FormMouseEnter(Sender: TObject);
begin
Label1.Caption := '';
end;
procedure TForm1.FormMouseLeave(Sender: TObject);
begin
Label1.Caption := 'left';
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if not PtInRect(ClientRect, TPoint.Create(x, y)) then Label1.Caption := 'left move';
end;
When the left button goes down, the VCL framework captures the mouse, if the control underneath the mouse has csCaptureMouse in its control style. When the mouse is captured, the WM_MOUSELEAVE messages are not generated until the capture is released. That happens when the left button goes up.
If you removed csCaptureMouse from the control underneath the mouse, then WM_MOUSELEAVE message would be generated as soon as the mouse left the window, because the mouse would not have been captured.
procedure TForm1.FormCreate(Sender: TObject);
begin
ControlStyle := ControlStyle - [csCaptureMouse];
end;
Of course, changing this style just to achieve this effect is surely not what you should be doing. I just point this out to show that the issue is due to an interaction between mouse capture and mouse tracking.
But mouse tracking and WM_MOUSELEAVE are not really what you are looking for I think. The WM_MOUSELEAVE is fired when you mouse over controls on your form, which is surely not what you want.
So I think that the approach outlined in Dalija's answer is actually the correct way to implement your desired behaviour in any case, irrespective of whether or not the mouse button is down.
I have been working with a wxpython control called objectlistview which makes it very easy to list objects directly in the listview. Is there a control similar to objectlistview in object pascal (lazarus in my case)?
I know how to attach an object to list, but its not the same, since the list/grid controls don't work directly with the objects.
In a form just drop a TTIPropertyGrid from the package RTTI controls.
Then in the code you can assign what the grid has to display, for example the current form itself:
procedure TForm1.FormCreate(Sender: TObject);
begin
TIPropertyGrid1.TIObject := self;
end;
How to make a form move in Delphi FMX also when you move the mouse fast. ?.
I have tried the code below but when you move the mouse to fast it stop's to work.
How to drag a borderless FMX form on the screen through another object?
Though it's mentioned in the post linked as a comment of OP I think it won't hurt to add it here too, as it's not the accepted answer over there some people searching for this at a later date may miss it. Also make sure it actually is the left mouse button, unless you want to have it drag with other buttons too.
procedure TMyForm.DragPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
if (Button = TMouseButton.mbLeft) then StartWindowDrag;
end;
Picture on the TImage is divided on a number of small rectangles and i need to check if user clicks on one of them. Basically, i need to create button on image without button itself. So, the question is: how to check if cursor is over a certain part of Image component?
Add an OnMouseDown or OnMouseUp event handler to TImage and check X and Y params.