DesktopCanvas

From Xojo Documentation

Class (inherits from DesktopUIControl)


New in 2021r3

DesktopCanvas controls are very useful for implementing your own graphical controls because you can use the Graphics class drawing commands or the Object2D classes to draw inside the Canvas region. It can also be used to display existing graphics, like the DesktopImageViewer.

Events
Activated DropObject MouseExit
Closing FocusLost MouseMove
ConstructContextualMenu FocusReceived MouseUp
ContextualMenuItemSelected KeyDown MouseWheel
Deactivated KeyUp Opening
DoublePressed MenuBarSelected Paint
DragEnter MouseDown ScaleFactorChanged
DragExit MouseDrag
DragOver MouseEnter
Properties
Active fa-lock-32.png Index fa-lock-32.png ScaleFactor
AllowAutoDeactivate Left Scope fa-lock-32.png
AllowFocus LockBottom TabIndex
AllowFocusRing LockLeft Tooltip
AllowTabStop LockRight Top
AllowTabs LockTop Transparent
Backdrop MouseCursor Visible
Enabled Name fa-lock-32.png Width
Handle fa-lock-32.png PanelIndex Window fa-lock-32.png
Height Parent
Methods
AcceptFileDrop AcceptTextDrop Refresh
AcceptPictureDrop Close Scroll
AcceptRawDataDrop DrawInto SetFocus

Notes

Coordinates passed to DesktopCanvas events are local to the DesktopCanvas object.

To use the Scroll method to scroll the picture in a DesktopCanvas control, you need to store the last scroll value for the axis you are scrolling so you can use this to calculate the amount to scroll. This can be done by adding properties to the window that contains the DesktopCanvas control or by creating a new class based on the DesktopCanvas control that contains properties to hold the last X scroll amount and last Y scroll amount.

If the ScrollControls parameter is True, any controls on top of the Canvas control will also be scrolled. This allows the implementation of a scrolling pane of controls.

The following example scrolls a picture that was added to the project. The properties XScroll and YScroll have been added to the window to hold the amounts the picture has been scrolled. The picture is scrolled 8 points at a time. In the Keydown event of the window, the following code calls the Scroll method whenever the Up, Down, Left, or Right arrow keys are pressed.

Const LeftArrow = 28
Const RightArrow = 29
Const UpArrow = 30
Const DownArrow = 31
Const ScrollUnit = 8 // points

Select Case Asc(Key)
Case LeftArrow
XScroll = XScroll + ScrollUnit
Canvas1.Scroll ScrollUnit, 0

Case RightArrow
XScroll = XScroll - ScrollUnit
Canvas1.Scroll -ScrollUnit, 0

Case UpArrow
YScroll = YScroll + ScrollUnit
Canvas1.Scroll 0, ScrollUnit

Case DownArrow
YScroll = YScroll - ScrollUnit
Canvas1.Scroll 0, -ScrollUnit

End Select

The Scroll method calls the Paint event of the canvas that redraws the picture with the new values of XScroll and YScroll. The Paint event has the following line of code:

g.DrawPicture(myPicture, Xscroll, Yscroll)

Sample Code

This code in the Paint event handler draws a simple red line:

g.DrawingColor = &cff0000
g.DrawLine(0, 10, 100, 100)

To simply draw a picture in a Canvas, use this code in the Paint event:

g.DrawPicture(PictureAddedToProject, 0, 0)

This code (in the Paint event) draws a 3D rectangle with a raised look.

Const White = &cffffff
Const DarkGray = &c8c8c8c
Const LightGray = &cefefef

g.ForeColor = White
g.DrawLine(1, 1, Me.Width, 1)
g.DrawLine(1, Me.Height - 1, 1, 1)
g.DrawingColor = DarkGray
g.DrawLine(Me.Width - 1, 2, Me.Width - 1, Me.Height)
g.DrawLine(1, Me.Height - 1, Me.Width, Me.Height - 1)

//fill in the light gray rectangle
g.DrawingColor = LightGray
g.DrawFilledRectangle(2, 2, Me.Width - 3, Me.Height - 3)

This code draws a gradient from Red to Blue:

Var startColor As Color = &cff0000
Var endColor As Color = &c0000ff

Var p As New Picture(g.Width, g.Height)

Var samt, eamt As Double

For i As Integer = 0 To p.Height
samt = 1 - (i / p.Height)
eamt = i / p.Height
p.Graphics.DrawingColor = RGB((startColor.Red * samt) + (endColor.Red * eamt), _
(startColor.Green *samt) + (endColor.Green * eamt), _
(startColor.Blue * samt) + (endColor.Blue * eamt))
p.Graphics.DrawLine(-1, i, p.Width + 1, i)
Next

g.DrawPicture(p, 0, 0)

This code assigns a picture that has been added to the Project Editor to the Backdrop property in the Open event:

Me.Backdrop = OSLogo

You can use the methods of the Graphics class to modify the picture in any way you like. For example, the following code in the object's Paint event handler adds a caption to the picture:

g.FontName = "Arial"
g.FontSize = 14
g.DrawingColor = &c0080C0
g.DrawText("Mary Jane", 10, 100)

If you instead assigned the graphic to the BackDrop property using the Picture constructor, as shown below, you could manipulate the graphic at the pixel level using the RGBSurface property of the Picture object.

Me.Backdrop = New Picture(210, 30)
Me.Backdrop.Graphics.DrawPicture(YourAppLogo, 0, 0)

See also the examples for the DesktopControl class, which give an example of dragging from a Canvas control and the DesktopImageViewer class example, which show drag and drop to and from the DesktopImageViewer.Image property.

Simulating a Focus Ring on Windows and Linux

Unfortunately, a Focus Ring does not appear on Windows or Linux when a DesktopCanvas control gets the focus, but the GotFocus and LostFocus events fire normally. You can easily use them to simulate a focus ring. Create a property on the window called mHasFocus As Boolean.

In the GotFocus event handler:

mHasFocus = True
Canvas1.Invalidate(False)

In the LostFocus event handler:

mHasFocus = False
Canvas1.Invalidate

In the Paint event handler for Canvas1:

#If TargetWindows Or TargetLinux Then
If mHasFocus Then
g.DrawingColor = HighlightColor // or FrameColor, whichever you wish
g.DrawRectangle(0, 0, Me.Width - 1, Me.Height - 1)
Else
g.DrawingColor = RGB(178, 178, 178) // gray
g.DrawRectangle(0, 0, Me.Width - 1, Me.Height - 1)
End If
#Endif

See Also

Graphics, Picture classes