B4J Question ABMaterial Canvas How-To.

techknight

Well-Known Member
Licensed User
Longtime User
Is there an AB material for dummies out there? I saw the examples website and it shows all the controls and features it has along with code, but its not really telling me on how everything works, or more importantly how to use anything. I just dont get it...

For example, something as easy as changing the background color of one of the cells to see where it shows up in the page? Nope no idea.

What about adding a scaled background image to the web page? Nope, not a clue....

any help would be appreciated.
 

techknight

Well-Known Member
Licensed User
Longtime User
I get that part, but Again I dont see how it is used in your code? All I see under the click events are a select case statement for negative numbers???

I use RealBasic/Xojo as well for mainly R-Pi console apps.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
I got the example running. I noticed though when using a touchscreen device like my phone, 1 tap is picking up multiple clicks. Dont know why?
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Is there a way to add a backcolor to a canvas object/rectangle?

I need to change that Start/stop button to RED when the clock is running.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
I need to change that Start/stop button to RED when the clock is running.
This is a bit tricky, but doable. :)

1. I've cut out the button from you picture (remember on what point x,y I've did the cut: in this case 430,185 and the picture was width=420 and height=100 pixels)
2. saved it to picgreen.png, colored it red and saved that one to picred.png

picgreen.png
picred.png


3. In our app, loaded both pictures in BuildPage(), right where we loaded the background

B4X:
page.AddCanvasImage("background", "../images/appimage.png")
page.AddCanvasImage("picgreen", "../images/picgreen.png")
page.AddCanvasImage("picred", "../images/picred.png")

4. I created a new DrawLabelWithPic method that, next to setting the label, also sets a background picture to the ABMCanvasObject

B4X:
Sub DrawLabelWithPic(LabelObject As ABMCanvasObject, Font As String, Size As Int, Color As String, Text As String, Pic As String, halfX As Int, halfY As Int)
   LabelObject.Clear
   ' because we 'centered' the origin for the text part, we neeed to undo what we have added for the image part
   LabelObject.drawImage(Pic, -halfX,-halfY) ' <---------------------
   LabelObject.font(Font, Size)
   LabelObject.textBaseline(ABM.CANVAS_TEXTBASELINE_MIDDLE)
   LabelObject.textAlign(ABM.CANVAS_TEXTALIGN_CENTER)
   LabelObject.fillStyleColor(Color)
   LabelObject.fillText(Text, 0, 0)   
End Sub

5. Changed the existing StartStopLabel to use this new method. I also Had to adjust the InitializeAsRectangle values to the new coordinates!

B4X:
Dim StartStopLabel As ABMCanvasObject
StartStopLabel.InitializeAsRectangle(page, "StartStopLabel", 430+(420/2),185+(100/2), 420, 100, False) ' NEW
DrawLabelWithPic(StartStopLabel, "arial", 40, "#000000", "Start Clock", "picgreen", 420/2, 100/2) ' NEW
myCanvas.AddObject(StartStopLabel)

6. finally, had to call this new method in the myCanvas_CanvasUp too

B4X:
Case -16711681
           Dim StartStopLabel As ABMCanvasObject = myCanvas.GetObject("StartStopLabel")
           If GameStart > 0 Then
               GameTimer.Enabled = False
               GameStart = 0               
               DrawLabelWithPic(StartStopLabel, "arial", 40, "#000000", "Start Clock", "picgreen", 420/2, 100/2) ' NEW
           Else
               GameTimer.Initialize("GameTimer", 1000)
               GameTimer.Enabled = True
               GameStart = DateTime.Now
               DrawLabelWithPic(StartStopLabel, "arial", 40, "#000000", "Stop Clock", "picred", 420/2, 100/2) ' NEW
           End If
           StartStopLabel.Refresh

Now when one clicks the button, the label text changes + it draws the background picture red/green.

Important here is the part where you 'cut' out the variable pictures. Make sure it is big enough (containing some of the normal background black in this case) so the user does not see that something is being drawed on top of the background.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
This is another helper method where you can build a label, with a rounded rectangle as background.

B4X:
Sub DrawLabelWithRect(LabelObject As ABMCanvasObject, Font As String, Size As Int, Color As String, Text As String, halfX As Int, halfY As Int, rectColor As String, rectBorderColor As String)
   LabelObject.Clear
   LabelObject.fillStyleColor(rectColor)
   LabelObject.strokeStyleColor(rectBorderColor)
   ' because we 'centered' the origin for the text part, we neeed to undo what we have added for the image part
   RoundRect(LabelObject, -halfX, -halfY,  halfX*2, halfY*2, 5, True, True)
   LabelObject.font(Font, Size)
   LabelObject.textBaseline(ABM.CANVAS_TEXTBASELINE_MIDDLE)
   LabelObject.textAlign(ABM.CANVAS_TEXTALIGN_CENTER)
   LabelObject.fillStyleColor(Color)
   LabelObject.fillText(Text, 0, 0)
End Sub

Sub RoundRect(labelObject As ABMCanvasObject, x As Int, y As Int, width As Int, height As Int, radius As Int , fill As Boolean, stroke As Boolean)
   labelObject.beginPath
   labelObject.moveTo(x + radius, y)
   labelObject.lineTo(x + width - radius, y)
   labelObject.quadraticCurveTo(x + width, y, x + width, y + radius)
   labelObject.lineTo(x + width, y + height - radius)
   labelObject.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
   labelObject.lineTo(x + radius, y + height)
   labelObject.quadraticCurveTo(x, y + height, x, y + height - radius)
   labelObject.lineTo(x, y + radius)
   labelObject.quadraticCurveTo(x, y, x + radius, y)
   labelObject.closePath
   If fill Then
       labelObject.fill
   End If
   If stroke Then
       labelObject.stroke
   End If
End Sub
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Thanks! Picture switching is basically what I had in mind. I have to do the same thing with the power button on top anyways. Red/Green.

Now I need a non-dissmissable indeterminate progress dialog. Like if the system is waiting on something, its a Modal style "please wait" Spinny circle dialog.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Not sure I follow.

Basically when the user connects, I am going to be initializing and booting up hardware in the background. So I would like an indefinate progress dialog so the user knows this is happening.

There is hte possibility that the hardware can fail, so it will throw up an alert box (which I have figured out thanks to searching here :)) saying hardware error. Call service, blah blah blah.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
When you are doing a rather long process on the server (e.g. initializing your hardware, running a long SQL, etc), you can do a page.pause at the beginning of your process (at that point the user is 'blocked' out from the app and will see e.g. a spinning thingy).

When you have finished your process, you do a page.resume, which removes the spinning thingy and the user can continue working with your app. There are, next to the default spin, six other animations you can use: https://www.b4x.com/android/forum/threads/abmaterial-6-new-loading-pause-animations-2-50.75656/

And if your hardware fails while the page is paused, you do a page.resume and e.g. show a messagebox.
 
  • Like
Reactions: udg
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Ok. Well thats still yet to be determined on how I am going to handle that. Thanks for the info.

Also, I am trying to change the way the "click" system works as I really dont want to build a whole complete image of multicolored buttons used to trigger the events. Although that works perfectly fine, I have tons of different layouts and I am not that good at graphics software to be able to "generate" these.

So, I decided to play around a bit by adding the objects as I am now, but using the "South Park" method.

Problem is, I cant get the ObjectUp event to fire!

I even commented out the CanvasDown/CanvasUp subs. But ObjectUp never fires.

B4X:
Sub myCanvas_ObjectUp(objectID As String)
'    Dim myCanvas As ABMCanvas = page.Component("myCanvas")
    Log("Object: " & objectID)
End Sub

any reason why?

Edit: Only fires if I make the object "draggable". yeck... I dont want that.
 
Last edited:
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
I ended up going with page.Pause and resume, that worked perfectly fine for my needs. Thanks.

By the way, the function you created DrawLabelwithRect, I want to be able to set the percentage of transparency, so I found a property called globalAlpha, however I cant find any explanation on its function or how its used.

can you elaborate?
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
globalAlpha
Where did you find that one? Is it directly from the library? If so, I don't think this should be exposed in B4J as changing it could get you in trouble.

As for transparency, you probably will have to use something like rgba(255, 0, 0, 0.5) for the color param. (untested)
 
Last edited:
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
it shows up as a list of available items when declaring something as ABMCanvasObject.

Also I think I may have found a bug, or I am not doing something right.

Example code:
B4X:
    Dim pnlTemp As ABMCanvasObject
    pnlTemp.InitializeAsRectangle(page, "pnltemp",500,500,100,100,True)
    pnlTemp.SetDragZone(500,500,0.001,0.001)
    DrawLabelWithRect(pnlTemp,"ariel","5","#FFFFFF","",50,50,"#ADFF2F","#ADFF2F")
    myCanvas.AddObject(pnlTemp)

It creates a clickable button for ObjectUp event, But, the clicky hand doesnt show up until you get to the center of the object, and about half the size of the object away from the object down to the right and bottom.

I added the SetDragZone as a way to stop you from dragging the item around.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Just tried rgba. its not working. There is no level of transparency with the background image.

Edit: Shows transparent once when I refreshed the page, I refreshed it again and it was full opaque. Grrrrrr
 
Last edited:
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
Wishes and Bugs are better added to the Feedback app, else they have a big chance to be forgotten.

My example for rgba was wrong, actually the rect should be transparent. Tested this and it worked:
B4X:
DrawLabelWithRect(StartStopLabel, "arial", 40, "#000000", "Start Clock", 420/2, 100/2, "rgba(0,255,0,0.5)", "#FFFFFF")
 
Upvote 0
Top