iOS Question What component to draw using finger

rfresh

Well-Known Member
Licensed User
Longtime User
What iOS component would I use to create a simple drawing app using your finger to draw with? I don't see a Canvas component in B4i like B4A has.

Thank you...
 

rfresh

Well-Known Member
Licensed User
Longtime User
Erel's Smily.zip program looks like a good starting point to make a simple finger drawing program.

What changes would I have to make to turn his bouncing smiley face tutorial into a simple finger drawing program?

Thank you...
 

Attachments

  • Smiley.zip
    4.7 KB · Views: 208
Upvote 0

rfresh

Well-Known Member
Licensed User
Longtime User
I’ll have a look at your tutorial.

When you say there is a canvas in B4i, why don’t I see one in the designer?

I’m a bit confused at the start of your tutorial. You’re using B4x. I’m using B4i. B4x allows more UI components to be used in my B4i app? I don’t understand yet the relationship between B4x and B4i?
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
When you say there is a canvas in B4i, why don’t I see one in the designer?
You don't see it in the designer because it is not a View, it is an object linked to a view the same as in B4A.
You don't see the B4A Canvas either in the Designer.

You may have a look at the B4X Graphics Booklet.
It explains in detail the Canavs objets for B4A, B4i, B4J and B4X, with examples and source code.
You may also have a look at the B4X XUI Booklet, which explains the XUI libraries.
 
Last edited:
Upvote 0

rfresh

Well-Known Member
Licensed User
Longtime User
I got the B4X Graphics tutorial First Steps working OK in my small test app below. All the tutorial Draw() routines worked great on the page and on the panel.

In B4A I have a pnlDrawing_Touch() sub that I use to do very simple finger drawing and it works fine on B4A.

I brought over that same code below (pnlDrawing_Touch() now as pnlGraph_Touch()) and made some small changes for B4i. The code below runs but when I touch and try to draw I don't see anything on the panel.

In debug mode, the event is firing when I touch and move (0 and 1 Case Statement).

B4X:
'Code module
#Region  Project Attributes
    #ApplicationLabel: B4i Example
    #Version: 1.0.0
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
    #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
    #Target: iPhone, iPad
    #ATSEnabled: True
    #MinVersion: 7
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
 
    Dim x1, x2, y1, y2, Radius, LineWidth As Float
    Dim LineColor As Int
    Dim rect1 As Rect
 
    Private pnlGraph As Panel
    Private cvsPage, cvsGraph As Canvas
 
End Sub

Private Sub Application_Start (Nav As NavigationController)
    'SetDebugAutoFlushLogs(True) 'Uncomment if program crashes before all logs are printed.
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
 
    'load the layout file
    Page1.RootPanel.LoadLayout("Main")
    ' show page 1
    NavControl.ShowPage(Page1)
    Radius = Floor(LineWidth / 2)
    LineColor = Colors.Magenta
    rect1.Initialize(0, 0, pnlGraph.Width, pnlGraph.Height)
End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)
    ' initialize the Canvas for the activity
    cvsPage.Initialize(Page1.RootPanel)
    ' initialize the Canvas for the pnlGraph panel
    cvsGraph.Initialize(pnlGraph)
    ' call the Drawing routine
    'Drawing 'not used
End Sub

Private Sub Application_Background
 
End Sub

Private Sub Drawing
    ' draw a horizontal line onto the Page
    'cvsPage.DrawLine(20, 20, 160, 20, Colors.Red, 3)
    ' draw a horizontal line onto pnlGraph
    'cvsGraph.DrawLine(20, 20, 160, 20, Colors.Red, 3)
    'cvsPage.Refresh
    'cvsGraph.Refresh
End Sub

'Draw a cross on the reference point
Private Sub DrawCross(x As Int, y As Int, l As Int)
    'cvsGraph.DrawLine(x - l, y, x + l, y, Colors.Red, 1)
    'cvsGraph.DrawLine(x, y - l, x, y +l, Colors.Red, 1)
End Sub



Sub pnlGraph_Touch(Action As Int, X As Float, Y As Float)
    Select Action
        'Case Activity.ACTION_DOWN 'used in B4A
        Case 0 'B4i
            x1 = X
            y1 = Y
            cvsGraph.DrawCircle(x1, y1, Radius, LineColor, True, 1)
            rect1.Left = x1 - Radius
            rect1.Top = y1 - Radius
            rect1.Right = rect1.Left + LineWidth
            rect1.Bottom = rect1.Top + LineWidth
            'pnlGraph.Invalidate2(rect1) 'b4A
            cvsPage.Refresh 'b4i
            cvsGraph.Refresh 'b4i
        'Case Activity.ACTION_MOVE
        Case 1
            x2 = X
            y2 = Y
            cvsGraph.DrawCircle(x1, y1, Radius, LineColor, True, 1)
            cvsGraph.DrawLine(x1, y1, x2, y2, LineColor, LineWidth)
            rect1.Left = Min(x1, x2) - Radius
            rect1.Top = Min(y1, y2) - Radius
            rect1.Right = Max(x1, x2) + LineWidth
            rect1.Bottom = Max(y1, y2) + LineWidth
            'pnlGraph.Invalidate2(rect1)
            cvsPage.Refresh
            cvsGraph.Refresh
            x1 = x2
            y1 = y2
    End Select
End Sub
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
It would be easier for us to help you if you posted your project as a zip file.

Suggestions:
1. Use the XUI library.

2. Replace
Private pnlGraph As Panel
Private cvsPage, cvsGraph As Canvas
by
Private pnlGraph As B4XViewl
Private cvsPage, cvsGraph As B4XCanvas

3. Change the Touch event routine to:
B4X:
Sub pnlGraph_Touch(Action As Int, X As Float, Y As Float)
    Select Action
        'Case Activity.ACTION_DOWN 'used in B4A
        Case pnlGraph.TOUCH_ACTION_DOWN
            x1 = X
            y1 = Y
            cvsGraph.DrawCircle(x1, y1, Radius, LineColor, True, 1)
            rect1.Left = x1 - Radius
            rect1.Top = y1 - Radius
            rect1.Right = rect1.Left + LineWidth
            rect1.Bottom = rect1.Top + LineWidth
            'pnlGraph.Invalidate2(rect1) 'b4A
           ' cvsPage.Refresh 'b4i
            cvsGraph.Invalidate
        'Case Activity.ACTION_MOVE
        Case pnlGraph.TOUCH_ACTION_MOVE
            x2 = X
            y2 = Y
            cvsGraph.DrawCircle(x1, y1, Radius, LineColor, True, 1)
            cvsGraph.DrawLine(x1, y1, x2, y2, LineColor, LineWidth)
            rect1.Left = Min(x1, x2) - Radius
            rect1.Top = Min(y1, y2) - Radius
            rect1.Right = Max(x1, x2) + LineWidth
            rect1.Bottom = Max(y1, y2) + LineWidth
            'pnlGraph.Invalidate2(rect1)
            'cvsPage.Refresh
            cvsGraph.Invalidate
            x1 = x2
            y1 = y2
    End Select
End Sub
 
Upvote 0

rfresh

Well-Known Member
Licensed User
Longtime User
Thank you Klaus. I made the changes you suggested, but I still don't see anything when I try to draw using my finger on my iPad.

.zip file attached.
 

Attachments

  • B4i.zip
    1.7 KB · Views: 208
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. There are many mistakes in this code.

2. The layout file is missing. You should use File - Export as zip.

As I wrote to you in another thread this code is wrong:
B4X:
pScreenHeight = GetDeviceLayoutValues.Height
   pScreenWidth = GetDeviceLayoutValues.Width
'..
pnlGraph.Width = pScreenWidth * 1.0
   pnlGraph.Height = pScreenHeight * 0.80
You should use anchors instead.

Or:
B4X:
    pnlGraph.Width = Width * 1.0
   pnlGraph.Height = Height* 0.80

You should call B4XCanvas.Resize instead of Initialize in Page_Resize event.

You are calling ShowPage twice.

LineWidth is always 0.

Use a single canvas. Remove the canvas that draws on the root panel. The canvas panel shouldn't hold any other views.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
In additipn to Erel's post, attached the code in B4X XUI, the B4J version:
Tested with B4J, currently I cannot test it with B4i I have some trouble with my Apple decices, will fix this next year.

B4X:
Sub Process_Globals
   Private fx As JFX
   Private MainForm As Form
   Private xui As XUI
  
   Private pnlGraph As B4XView
   Private cvsGraph As B4XCanvas

   Private x1, x2, y1, y2, Radius, LineWidth As Float
   Private LineColor As Int

End Sub

Sub AppStart (Form1 As Form, Args() As String)
   MainForm = Form1
   MainForm.RootPane.LoadLayout("Main") 'Load the layout file.
   MainForm.Show
  
   cvsGraph.Initialize(pnlGraph)
   LineColor = xui.Color_Blue
   Radius = 2dip
   LineWidth = 5dip
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
   Return True
End Sub

Private Sub pnlGraph_Touch(Action As Int, X As Float, Y As Float)
   Select Action
       Case pnlGraph.TOUCH_ACTION_DOWN
           x1 = X
           y1 = Y
           cvsGraph.DrawCircle(x1, y1, Radius, LineColor, True, 1)
           cvsGraph.Invalidate
       Case pnlGraph.TOUCH_ACTION_MOVE
           x2 = X
           y2 = Y
           cvsGraph.DrawCircle(x1, y1, Radius, LineColor, True, 1)
           cvsGraph.DrawLine(x1, y1, x2, y2, LineColor, LineWidth)
           cvsGraph.Invalidate
           x1 = x2
           y1 = y2
   End Select
End Sub

Another problem is that you didn't set any values to:
B4X:
LineColor = xui.Color_Blue
Radius = 2dip
LineWidth = 5dip
And with LineColor = 0, the default value, the color is transparent so you won't see anything on a white backgraound.
 
Upvote 0

rfresh

Well-Known Member
Licensed User
Longtime User
Thank you very much Erel and Klaus. I've made all the changes you've both pointed out. I can now see lines when I finger draw!

As the attachment shows, the black lines I added to show my finger movement downward. The red is what the code is drawing. The middle black line down is again my finger movement and the red line to its right is what the code is doing. There is an offset somehow and it gets more offset (to the right) the further to the right I touch and move.

I'm not sure why I'm getting this offset. I looked at the code (correctly saved .zip file attached) but I can't figure out what is causing it.
 

Attachments

  • 2018-12-31_091638.png
    36.7 KB · Views: 191
  • Graphics1b4i.zip
    3.7 KB · Views: 192
Upvote 0

ilan

Expert
Licensed User
Longtime User

the reason for that is that you initialize the canvas before you set the pnl coordinates in your resize event.
you need to initialize the canvas AFTER setting all coordinates.

B4X:
Private Sub Page1_Resize(Width As Int, Height As Int)
    'cvsPage.Initialize(Page1.RootPanel)
    'cvsGraph.Resize(Width, Height)
    
    pnlGraph.Top = Height * 0.20
    pnlGraph.Left = 0
    pnlGraph.Width = Width
    pnlGraph.Height = Height * 0.56
    
    cvsGraph.Initialize(pnlGraph)
    
    'Msgbox("Grn 121.9 * Twr 118.5 * App 125.5"& CRLF & "Grn 121.9 * Twr 118.5 * App 125.5", "KMEM")
    Drawing

that should fix your problem
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…