Android Question New user learning - any guidance please?

SparkOut

New Member
Hi there, new user here, I just discovered B4X a few weeks ago thanks to a comment made in a different forum related to LiveCode.
I'm not a programmer, so the LiveCode "English-like" syntax has been my way into getting apps and tools made, sometimes for hobbying, sometimes for doing something bespoke (but relatively small scale) to help for work. These days I don't have the same requirements and haven't actually even opened the LiveCode IDE more than a couple of times this year, so I'm finding the idea of paying another year of subscription is hard to justify. Hence the discovery of B4X was very interesting, although I've not got any problems with LiveCode.

So I spent a couple of weeks watching all Erel's videos and finding a lot of useful info and then at the weekend, for the experience, I started to try converting an old app I had made many years ago (for desktop and Android) to solve "Alphactor" puzzles (where values are attributed to letters and then a word's total value is shown, with a total sum of the word list values).

I quickly found that there is a big shift needed in understanding the anatomy of a project. A LOT of what I am going to relate will sound like complaints, and maybe some of them are, but it's not my intention to tear down B4X - I really want to get used to working in it and I do see a lot of value here, and really appreciate the efforts of Erel and everyone in the community. I do NOT want to be saying "you should do it like this" - mentioning some of my pain points will hopefully help people to show me where I can translate from LiveCode mindset - I need to learn and understand, and maybe give a few hints where there could be some better handholding for new users.

I quickly found that although there is a LOT of information in the forum here, it's VERY unclear how much of it is relevant and useful today. There really needs to be some bigger signposts for the walkthrough of getting a new user onboarded. I spent a lot of time digging through results of searches that mostly seemed to be over 10 years old, and of course in some cases the language hasn't changed, and in many it has been updated (B4X & Xui).

Persevering with the project, I quickly got a layout built. OK, the designer is limited. Even for a static display, there's no way to select a group of views and align them, match sizes or distribution. So I tried the Designer Script, and worked with that. Which is great, but then it doesn't update the WYSIWYG view, and doesn't do loops, and here's one of the big paradigm shifts to get my head around - you can't programmatically create a view name and have that automatically cast to the view object reference. At least as far as I can tell. Designer script OK, I'm happy with the layout.

So to begin the puzzle solving process, I take the fldWords.text value and do some very rudimentary error trapping to set all upper case, remove spaces and blank lines
B4X:
Sub TrimAndFix(pText As String) As String
    pText = pText.ToUpperCase
    Do While pText.Contains(CRLF & CRLF)
        pText = pText.Replace(CRLF & CRLF,CRLF)
    Loop
    pText = pText.Replace(" ","")
    Return pText
End Sub
It was easy enough to obtain the text, and put back into the view after correcting, then compare the number of words to the number of the values (I'll do more error trapping in due course).

In the logic of the app, there is quite a heavy use of a dynamic multidimensional matrix containing the values for each letter which are traversed, recalculated, pivoted with other items in different rows, set and updated as the solution algorithm processes it. In LiveCode it's very simple to address any element indexed by any number of dimensions, in a variety of containers. In the case of the app to port, the data is in a simple string variable and elements are referred to directly and can get and set "item i of line l of sMatrix". I translated this to B4X by declaring Private sMatrix as List in the Class_Globals sub. To populate the original data rows, I iterated through the words list and declared and initialized a new List, did the letter counts and then sMatrixLine.Add(Count). Once each word's letter count had been fully populated, using sMatrix.Add(sMatrixLine) built up the matrix data as a List of Lists. So far so good.

But how do I access individual elements of the big matrix? For the outer loop to iterate through the lines of counts it is simple but how to take a value at a given index of each of those lines, without being able to address a list with a multidimenisional index? I don't know whether there's a "better/more concise/more approved/more elegant/more efficient" way than
B4X:
For tLine = 0 To sMatrix.Size - 1
   Dim sMatrixLine As List
   sMatrixLine.Initialize
   sMatrixLine = sMatrix.Get(tLine)
   For tLoop = 0 to sMatrixLine.Size -1
      'work on each element in the matrix and process accordingly
   Next
Next
The processing involves a lot of comparison of data in other indexed rows of the matrix and transposition of different values after performing operations on them. I'm uncertain of the best way to do this without continually creating temporary Lists, accessing an index of it, and then taking a whole row from the master sMatrix, updating an element in that and then replacing the whole row back into sMatrix.

So anyway, after working out at least "this" way of manipulating the data, I was left with a master matrix that showed the same data as the original LiveCode app. Great! Job done, sort of. Let's take the data and display the solution with each letter view having the value inserted. OK... how do I iterate through the matrix and put the relevant value into the relevant view? The view names I have set as "fldA", "fldB" etc but could just as easily be alphanumeric "fld0" for A, "fld1" for B etc. But I can see no way to take the value for letter A and do something like
B4X:
("fld" & Loop).Text = Answer
I found on the forum a suggestion to make a map of objects keyed by tag name at the start of the app with
B4X:
    For Each v As B4XView In sResultFlds
        mFields.Put(v.Tag, v)
    Next
and then retrieve the object by tag with
B4X:
Sub GetView(viewRef As String) As B4XView
    Dim v As B4XView
    v = mFields.Get(viewRef)
    Return v
End Sub
That works but I'm not really very clear about what is being done in the map - I'm a bit uneasy that I'm creating new objects that clutter up the app, or is it passing the view by reference? I think I get that in the GetView sub each view reference is created, returned and destroyed but then how does the returned object refer to the view if it's already destroyed?

Now I think I've got a working app, trying it out on my phone it works with the prebuilt default list of words and values. But that's not going to work for people to put in their own puzzles for solving. So I need to allow editing of the words and values and in the designer the values view has been set with a keyboard type of Numbers. Trying to edit the column of number values proves a problem though, although the keyboard shows a CR key, it has no effect in the view. Pasting a column of values from elsewhere also then strips out the CRs and gives a long string of numbers in the top line. How do I deal with this?

How do I edit the app title and icon in the titlebar? In the layout designer under Main Properties I have changed the Form Title. I have named the layout differently and used the new name in the LoadLayout call of the B4XMainPage Private Sub. The Form Title set in the designer seems to have no effect, and the icon option shows and empty set of choices and can't edit/paste anything in there.

So I hope I sound like I mean to, that is "encouraged but somewhat daunted, and frustrated by blundering around without signposts" - at least ones that I can be sure are pointing the right way and not to the old ghost town.

Any help for a new user to get to grips with the concepts involved?
 

SparkOut

New Member
Screenshots of the B4J version, although I'm also creating the app for Android. I can't see how to change the title.
1762611251861.png

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("AlphactorSolver")
    sMatrix.Initialize
End Sub
1762611105894.png

1762611133154.png
 
Upvote 0

walt61

Well-Known Member
Licensed User
Longtime User
Welcome to B4X, @SparkOut ; below some (hopefully useful) hints. If you didn't already, you may also want to have a look at @klaus 's booklets - see the first link on https://www.b4x.com/android/documentation.html

But how do I access individual elements of the big matrix?
sMatrixLine is an Object. Therefore, if you change a value in that list, it is changed in the parent list (sMatrix) as well (an object is always accessed by reference [pointers], not by value).
B4X:
Dim oneItem As String = sMatrixLine.Get(i) ' Get the item at index 'i'
sMatrixLine.Set(i, "Something new") ' Set the item at index 'i' to string "Something new"; instead of a string, any object can be used as well ('oneItem' must then be properly declared too)
Dim theSameLine As List = sMatrixLine ' theSameLine is now the same object as sMatrixLine
theSameLine.Set(i, "Something even newer") ' This change happens in sMatrixLine (and sMatrix), as we're working with objects

I'm not really very clear about what is being done in the map
When you store objects in a map, they are indeed passed by reference (a pointer), e.g.:
B4X:
Dim myMap As Map
myMap.Initialize
Dim lbl As Label
myMap.Put("label1", lbl)
Dim lbl2 As Label = myMap.Get("label1") ' lbl2 points to the same object as lbl; changes made to lbl2 are actually made to lbl; the object is not destroyed as long as you stay within its scope, e.g. myMap could be declared globally, while lbl2 could be declared in a Sub

How do I edit the app title and icon in the titlebar?
If the app is a B4XPages one (recommended), set the title with:
B4X:
 B4XPages.SetTitle(thePage, "The title") ' Use the proper value for 'thePage'
If not - not recommended, especially as you work cross-platform:
B4X:
Activity.Title = "My title" ' B4A
MainForm.Title = "My title" ' B4J

How do I set the form icon in Designer?
Click the 'Files' tab in the Designer (underneath the left hand pane), then 'Add Files', and add the icon's file there. Then, you'll be able to assign it to the Form.

Hope this helps!
 
Upvote 0
Top