B4J Question Set canvas borders when resize it, without clear current content

max123

Well-Known Member
Licensed User
Longtime User
I all,

I admit I've done much more difficult things, but I'm stuck here.

I need to make sure that when resizing the form (so even the Canvas that fit it), the 2 pixel wide red border is always shown, as in the first image attached, but without deleting the current content.

I've tried various ways but without success.

Does anyone understand how to do it?

Here is my simple code
Note, here the mainPnl is a panel on the designer, it fits the window and canvas is initialized to it.

Many thanks for help.

B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
 
    Dim cvs As B4XCanvas
    Private mainPnl As Pane
    Private fnt As Font
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
 
    fnt = fx.CreateFont("Monospace",12,True,False)
    cvs.Initialize(mainPnl)
    Clear
    cvs.DrawText("I have to stay here when the canvas changes size", 50, 200, fx.CreateFont("Monospace",18,True,False), xui.Color_Cyan, "LEFT")
End Sub

Sub MainForm_Resize (Width As Double, Height As Double)
    cvs.Resize(Width,Height)
    ShowScreenDimensions
    ShowBorders
End Sub

Sub Clear
    Dim rect As B4XRect
    rect.Initialize(0, 0, cvs.TargetRect.Width, cvs.TargetRect.Height)
    cvs.DrawRect(rect, xui.Color_Black, True, 1)
End Sub

Sub ShowScreenDimensions
    Dim rect As B4XRect
    rect.Initialize(1, 1, 130dip, 80dip)
    cvs.DrawRect(rect, xui.Color_Black, True, 1)
 
    cvs.DrawText("DPI:    " & (96*Density), 20dip, 25dip, fnt, xui.Color_White, "LEFT")
    cvs.DrawText("Scale:  " & Density, 20dip, 38dip, fnt, xui.Color_White, "LEFT")
    cvs.DrawText("Width:  " & mainPnl.Width,20dip, 51dip, fnt, xui.Color_Yellow, "LEFT")
    cvs.DrawText("Height: " & mainPnl.Height,20dip, 64dip, fnt, xui.Color_Yellow, "LEFT")
    cvs.Invalidate
End Sub

Sub ShowBorders
'    Clear
    Dim rect As B4XRect
    rect.Initialize(1, 1, 1+cvs.TargetRect.Width-2, 1+cvs.TargetRect.Height-2)
'    cvs.DrawRect(rect, xui.Color_Black,False,2)
    cvs.DrawRect(rect, xui.Color_Red,False,2)
    cvs.Invalidate
End Sub
 

Attachments

  • Screenshot 2025-04-17 145345.png
    Screenshot 2025-04-17 145345.png
    28.1 KB · Views: 137
  • Screenshot 2025-04-17 145442.png
    Screenshot 2025-04-17 145442.png
    29.8 KB · Views: 128
Last edited:

stevel05

Expert
Licensed User
Longtime User
You have a comment 'Clear in Sub ShowBorders, but don't appear to be actually clearing the previous border. You may need to make the clear rect slightly larger to clear all pixels.

If that doesn't help. Post your test project so we can try it out.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
The other option which usually helps, is to have a second canvas for 'static' drawings i.e. the border, which is then easy to update.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Many thanks @stevel05,
the comment 'Clear' in Sub ShowBorders is commented for the test, but it should be commented because it clear the actual canvas content.

I like your idea of second canvas, but it should be just at background (z order) because I put on top of the canvas view some controls that fires events, like buttons and so on, and they should be clickable.
May I can create another canvas and do the same for the infos printed on top-left so they do not cleard when clear the drawing canvas.

I put here the small demo project test.
Please, can you help me figure out with 3 separated canvases, eg. cvs1, cvs2, cvs3 ?
I mean one for drawings, one for infos and one for red borders.

Many thanks
 

Attachments

  • CanvasBorders.zip
    2.1 KB · Views: 92
Last edited:
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
I tried this, but something is wrong. I can initialize 3 canvases on the same Pane or I need to put 3 different Panes ?
 

Attachments

  • CanvasBorders2.zip
    2.3 KB · Views: 99
Last edited:
Upvote 0

stevel05

Expert
Licensed User
Longtime User
The only way I could get it to work was to make the rootpane the background colour. It appears that as soon as you rill any of the canvases with a colour it stops the rest displaying.

You also need to refresh the text as if you made the screen smaller than the text, some of it disappeared.
 

Attachments

  • CanvasBorders-sl.zip
    2.6 KB · Views: 86
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Possibly using 4 panes would work too, just gets a bit more complicated. If I remember correctly, the canvas draws on the background of the pane.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
You need one Pane as a B4XView for each B4XCanvas.
I would do it that way:
- Draw the background, black color plus red border.
- Draw the info on a transparent pane.
- Draw whatever you want on the third pane.
But, when you resize the form, you need to redraw everything.
 

Attachments

  • CanvasBorders3.zip
    2.2 KB · Views: 93
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Thanks @stevel05 and @klaus for your appreciated help.

I not yet tried your codes, so what is the best, the first one or the last one ?
But, when you resize the form, you need to redraw everything.
This is to avoid, if this happen I have to remove red borders, so I will study a solution.
 
Last edited:
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
@klaus your solution works, but I don't know because other canvas conflicts with the main drawing canvas and remove it's content.
Because I need the content is not cleared, I cannot use this solution.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Depending on what you want to draw you might need one Pane / Canvas more like for a cursor.
Attached the modified program.
You can draw lines.
Mouse down: begin point.
Mouse move: draws a dynamic line on cvsCursor
Mouse up: erases the dynamic line and draw the line on cvsDrawing.
After having drawn some lines, if you increase the size of the form, the lines remain.
But if you decrease the size of the form, the parts outsides the new new form size will disappear.
And if you increase again these parts will not appear again you need to redraw them.
Meaning you need to memorize what you have drawn to be able to redraw them.

You can consider the different pairs of Panas and Canvases as layers.

For the text i would suggest you to use B4XFonts, that way your project is directly cross-platform.
 

Attachments

  • CanvasBorders4.zip
    2.4 KB · Views: 98
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
If you want to resize you cannot keep the drawing.
Yes @klaus, but without draw the borders the content is retained, I tried just now, so the only solution for me if not others, I have to completely remove the red borders.
This app is an app I've developed for desktop and Android, it is the same app, but on Android (where screen is not resizes) I have the red borders.
May I can just add borders once at startup (in resize event), then remove them when the app is resized by user.

I will try your last project.
Many Thanks for your advices.
 
Last edited:
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
I saw your post after having posted my previous one.
If you want to resize you cannot keep the drawing.
Another time, I do not know because this is not possible if I use 3 different panels and 3 different canvas.

Now I'm just curious to know it before I remove borders at first resize after startup, so the second call to MainForm_Resize.

Can someone explain this ?

They are completely different controls, just in different z-order, so they should be able to get each it's work without conflict with others.

May even the Borders canvas (like infos)(we call it layer) should be just transparent and use clearRect instead of drawRect black color ?
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
This app is an app I've developed for desktop and Android, it is the same app,
Another time, I do not know because this not possible if I use 3 different panels and canvas, now I'm just curious to know it before I remove borders at first resize after startup, so the second call to MainForm_Resize.
The problem is that when you resize the Pane and the Canvas the canvas' bitmap is changed.
What do you expect when you decrease the form size and increase it again afterwards ?
The part of the form outsides the the new reduced form size is lost !
You ask a question, but do not explain clearly what your problem is.
What is the goal of the red border ?
What do you want do draw ?
Do you memorize what you have drawn ?
Why do you want to resize the form ?
Quite some questions, but without knowing what exactly you want to do, impossible to give any concrete advice, at least for me.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Thanks, I'm too not at PC now, but with phone. In theory it sholuld work even with 3 canvas because they are completely different controls, just have to be transparents.

I will try your code to know what you do, many thanks.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
The problem is that when you resize the Pane and the Canvas the canvas' bitmap is changed.
What do you expect when you decrease the form size and increase it again afterwards ?
The part of the form outsides the the new reduced form size is lost !
You ask a question, but do not explain clearly what your problem is.
What is the goal of the red border ?
What do you want do draw ?
Do you memorize what you have drawn ?
Why do you want to resize the form ?
Quite some questions, but without knowing what exactly you want to do, impossible to give any concrete advice, at least for me.
@klaus you says:
The problem is that when you resize the Pane and the Canvas the canvas' bitmap is changed.
What do you expect when you decrease the form size and increase it again afterwards ?
I expect the canvas drawing not change at all, not if I increase the canvas size, not if I decrease it, like just a simple single canvas.

I will search to explain a bit what I do.

I do not directly draw on Canvas by code, instead is ESP8266 or ESP32 microcontroller (where I developed a library called VirtualDisplay in Arduino environment) that send calls over WiFi UDP to my app. I created here a full wrapper of B4XCanvas and ESP can draw to PC and Android devices the same way I can do it from B4X side by code, but just max 1000-2000 commands every second.

So it is a virtual display over WiFi, with large and adaptable screen sizes and with 16 milion of colors instead of low resolution and 65k colors of any TFT screen.

They works over network, even works over internet, not just on local network.

Note that when I resize the Form, so, even the canvas that fit it, ESP know instantly the new dimensions over WiFi, I even implemented percentX(num) and percentY(num) so the layout can be scaled depending on remote device resoultion where the app run.

The red borders only are needed to better know the actual screen size, marked by red borders.
Why do you want to resize the form ?
Because on desktop devices, it acts like a normal app you can rezize. The user can resize the app form and the screen size seen from remote microcontroller will change, here the user can decide to redraw anything in a scaled way, but is not mandatory, as on B4X side, if percentual XY are used, and the canvas is scaled and then redrawn, all content will be scaled. But generally this not happen, depends on what the user need.

Actually if I have a small canvas and draw on it eg. at 1500 (X) and 1500 (Y) (out of it's dimensions), when I resize the form bigger, I can see the drawings, if I resize smaller I do not see drawings, but they not cleared, just are covered. When I increase the size the drawings reappears again.

This is what I have to obtain, but with even the red borders.

Actually I can get it, but using just one canvas, when I resize it, I have to clear it before redraw red borders, if I do not redraw I see all red lines when I resize bigger.

I hope it's clear, if you have some question I will reply.

Thanks
 
Last edited:
Upvote 0
Top