Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 14 total
Thread TPaint / Canvas
Fri, May 6 2016 8:08 AMPermanent Link

thomh

Hello,

So I have managed quite easily using TPaint to draw rectangles with a mouse and coding the OnMouse... events.

Now I would like to be able to f.ex. Shift + MouseClick one of these existing rectangles and resize it
or move it somewhere else.

Is this possible to do using TPaint?

// Thom
Fri, May 6 2016 9:21 AMPermanent Link

Matthew Jones

thomh wrote:

> So I have managed quite easily using TPaint to draw rectangles with a
> mouse and coding the OnMouse... events.
>
> Now I would like to be able to f.ex. Shift + MouseClick one of these
> existing rectangles and resize it or move it somewhere else.
>
> Is this possible to do using TPaint?

Yes, and no. 8-)

It is just a canvas on which you can paint, but it can respond to the
mouse. So just as with Windows, you would have to be able to repeat the
painting any time you want, and then respond to events. You'd do this
by creating a set of shape objects, and know where they are etc. Then
to draw the picture you'd ask each item to draw itself to the canvas.
When a mouse click occurs, you'd find the object at that location and
manipulate it accordingly, and then redraw the whole thing again, etc.

--

Matthew Jones
Fri, May 6 2016 9:58 AMPermanent Link

thomh

Thanks, Matthew.

When you say shape objects do you mean something like f.ex the TRect object?
And how do you go about drawing that object to the canvas?

// Thom
Fri, May 6 2016 10:15 AMPermanent Link

Matthew Jones

thomh wrote:

> When you say shape objects do you mean something like f.ex the TRect
> object?  And how do you go about drawing that object to the canvas?

Yes, exactly, except define your own. This becomes classic object
oriented programming - define a TShape base class, then a TRectShape
and TCircleShape. You can then have a virtual "DrawToCanvas" function
that is called by the controller as it runs down the list, etc.
TRectShape.DrawToCanvas will have the code you have now to draw a
rectangle. You'd then add "IsMouseHit" or something better named to
take an X,Y and return if the mouse is clicked on it, and if so, that's
the selected item. Etc.

--

Matthew Jones
Mon, May 9 2016 2:57 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Thom,

<< So I have managed quite easily using TPaint to draw rectangles with a mouse and coding the OnMouse... events.

Now I would like to be able to f.ex. Shift + MouseClick one of these existing rectangles and resize it or move it somewhere else.

Is this possible to do using TPaint? >>

Yes, but I would recommend a hybrid approach if you're attempting to manage "elements" in your UI.  You can do this by putting a TPaint control on a container panel, and then have it stretch to fit the whole container.  Then, you can also just create your rectangles as normal controls that are parented to the container, but are *on top* of the canvas in the display order.  That way you get the best of both worlds, and managing your rectangles will be a *lot* easier in terms of mouse/touch handling.

Tim Young
Elevate Software
www.elevatesoft.com
Thu, May 12 2016 12:27 PMPermanent Link

thomh

Thanks Tim and Matthew.

Tim,

I am very newbie-isn when it comes to this kind of programming so would it possible for a quick example of how to go best go about doing this.

Thanks in advance.

// Thom

Thu, May 12 2016 2:29 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Thom,

<< I am very newbie-isn when it comes to this kind of programming so would it possible for a quick example of how to go best go about doing this. >>

Check out the Paint example that ships with EWB.  Open that project up and start dropping TBasicPanel controls on top of the TPaint control (they'll actually be parented to the form).

You'll still need to code the mouse capturing, which means creating a TBasicPanel descendant component, but you can use a TSizeGrip control on each panel to allow for resizing.

Check out the WebSizer unit for more information on using the mouse/touch capturing capabilities to perform resizing/dragging.

Tim Young
Elevate Software
www.elevatesoft.com
Fri, May 20 2016 9:31 AMPermanent Link

thomh

Thanks, Tim.

Have tested a bit and can now create regions (inherited from TBasicPanel) at runtime, select them and move them. However, when I try to delete them I get the following error:

"Unable to get property 'tcomponent_fdestroying' of undefined or null reference
Line 12525"

I create a region like this:

     LRegion := TRegion.Create(ScrollPanel);
     LRegion.Parent := ScrollPanel;

Delete code:

     for i := ScrollPanel.ControlCount - 1 downto 0 do
     begin
       c := ScrollPanel.Controls[i];
       if (TControl(c) is TRegion) and
          (TControl(c).Tag = TRegion(Sender).Tag) then
       begin
         TControl(c).free;
         Break;
       end;
     end;

The region is deleted but I get the above error message.

Thanks for your help.

// Thom
Fri, May 20 2016 10:45 AMPermanent Link

Matthew Jones

thomh wrote:

>       LRegion := TRegion.Create(ScrollPanel);
>       LRegion.Parent := ScrollPanel;

I've compared that to my code, and the only difference is I don't
assign the parent. If commenting that out doesn't fix it, or breaks it
in other ways, look for something else, or better yet, open it in
Chrome, hit F12, and look at the javascript to see if you can see what
is happening.

--

Matthew Jones
Sun, May 22 2016 6:36 AMPermanent Link

thomh

>>I've compared that to my code, and the only difference is I don't
>>assign the parent. If commenting that out doesn't fix it, or breaks it
>>in other ways, look for something else, or better yet, open it in
>>Chrome, hit F12, and look at the javascript to see if you can see what
>>is happening.

Thanks, Matthew.

I created a simple test application with just a form. I use this code to create some TBasicPanel controls.
The FStartX and FStartY are just variables set in the OnMouseDown event of the form.
I get the same error with or without assigning the .Parent property.

     LRegion := TBasicPanel.Create(Form1);
     LRegion.Parent := Form1;
     LRegion.Border.Left.Visible := True;
     LRegion.Border.Left.Width := 1;
     LRegion.Border.Top.Visible := True;
     LRegion.Border.Top.Width := 1;
     LRegion.Border.Right.Visible := True;
     LRegion.Border.Right.Width := 1;
     LRegion.Border.Bottom.Visible := True;
     LRegion.Border.Bottom.Width := 1;
     LRegion.Opacity := 35;
     LRegion.Left := FStartX;
     LRegion.Top := FStartY;
     LRegion.Height := 30;
     LRegion.Width := 100;
     LRegion.OnMouseDown := Form1MouseDown;
     FRegionCounter := FRegionCounter + 1;
     LRegion.Tag := FRegionCounter;
     LRegion.Name := 'Region' + IntToStr(FRegionCounter);
     LRegion.BringToFront;

And I use this code to delete the selected one:

   if Sender is TBasicPanel then
   begin
     for i := Form1.ControlCount - 1 downto 0 do
     begin
       c := Form1.Controls[i];
       if (TControl(c) is TBasicPanel) and
          (TControl(c).Tag = TBasicPanel(Sender).Tag) then
       begin
         TControl(c).free;
         Break;
       end;
     end;
   end

which results in error:

"Unable to get property 'tcomponent_fdestroying' of undefined or null reference
Line 12448"

The Javascript code looks like this:

webui_telement.$p.triggerevent = function(id, aelement)
{
  var $t = this, $r;
  if (!$t.telement_fcontroller.tcomponent_fdestroying) // **** THIS IS WHERE IT FAILS
  {
     if (id == webui_cdinput)
        aelement.dochanged(webui_ecinputvaluechanged);
     $r = $t.telement_fcontroller.dispatchevent(id, aelement);
  }
  else
     $r = false;
  return $r;
};

Hopefully Tim will respond.

// Thom
Page 1 of 2Next Page
Jump to Page:  1 2
Image