QUIZ...

ilan

Expert
Licensed User
Longtime User
i have a table of 25 squares from left to the right and 15 squares from top to bottom

all drawn with canvas to a panel now if i touch somewhere in my panel i would like to fill that square where my finger is. so i need to get the index as an int to know what square i should fill.

how would you do that??

first square is index 0 last is 374

(Note that the index is returned on pnl.touch event (move, down)) so you should think for a fast and clean code) ;)

q1.jpg
 

ilan

Expert
Licensed User
Longtime User
i am using:

B4X:
Log((Abs(EventData.Y/cellwidht)*raww) + Abs(EventData.X/cellwidht))

in b4a the ABS is working but when i use it in b4j i am still getting a double. is there a bug?

before i get the index with a loop but then i discovered the shorter way like you answered, great thinking erel :)
 
Last edited:

ilan

Expert
Licensed User
Longtime User
Full B4j code:

B4X:
#Region  Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 400
#End Region

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim c As Canvas
    Dim cellwidht As Float
    Dim const raww = 25, rawh = 15 As Int
    Type cell(left As Float,top As Float,right As Float,bottom As Float,used As Boolean, color As Object)
    Dim pixellist As List
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.SetFormStyle("UNIFIED")
    MainForm.Show
    pixellist.Initialize
    c.Initialize("C")
    cellwidht = MainForm.Width / raww
    MainForm.RootPane.AddNode(c, 0, 0, MainForm.Width, MainForm.Height)
    drawgrid(raww, rawh)
End Sub

Sub drawgrid(sizex As Int,sizeh As Int)
    pixellist.Clear
    Dim pixel(sizex*sizeh) As cell

    For i = 0 To sizex - 1
        C.DrawLine(i*cellwidht,0,i*cellwidht,cellwidht*sizeh,fx.Colors.Black,0)
    Next  
  
    For i = 0 To sizeh
        C.DrawLine(0,i*cellwidht,MainForm.Width,i*cellwidht,fx.Colors.Black,0)
        If i = sizeh Then Exit 'only to draw the last line on the bottom
      
        For i2 = 0 To sizex -1
            Dim pos As Int = (i*sizex) + i2
            pixel(pos).left = i2*cellwidht
            pixel(pos).right = (i2*cellwidht) + cellwidht
            pixel(pos).top = i*cellwidht
            pixel(pos).bottom = (i*cellwidht) + cellwidht
            pixel(pos).used = False
            pixel(pos).color = fx.Colors.White
            pixellist.Add(pixel(pos))
        Next              
    Next  
End Sub

Sub fillsquare(index As Int)
    Dim selcell As cell = pixellist.Get(index)
    If selcell.used = False Then
        selcell.used = True
        c.DrawRect(selcell.left,selcell.top,cellwidht,cellwidht,fx.Colors.Green,True,0)
        c.DrawRect(selcell.left,selcell.top,cellwidht,cellwidht,fx.Colors.Black,False,1)
        selcell.color = fx.Colors.Green
    Else
        'Log("cell is allready used")
    End If
End Sub

Sub selected_index(geti As Int)
    fillsquare(geti)
End Sub

Sub MainForm_MousePressed (EventData As MouseEvent)
    selected_index((Floor(EventData.Y / cellwidht) * raww) + Floor(EventData.X / cellwidht))
End Sub

Sub MainForm_MouseDragged (EventData As MouseEvent)
    selected_index((Floor(EventData.Y / cellwidht) * raww) + Floor(EventData.X / cellwidht))
End Sub

but still i dont know why the ABS is not working??? :confused:
 
Last edited:

ilan

Expert
Licensed User
Longtime User
ABS will do nothing useful here as the numbers are always positive. You should use Floor instead.

Don't repeat the same code twice. Create another sub and call it from both events.

:oops: oopppss

thank you very much @Erel :)

i mixed abs with floor, i updated the code is it correct now?
 
Last edited:
Top