Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Announcing Visual Small Basic #172

Open
VBAndCs opened this issue Dec 25, 2020 · 17 comments
Open

Announcing Visual Small Basic #172

VBAndCs opened this issue Dec 25, 2020 · 17 comments

Comments

@VBAndCs
Copy link

VBAndCs commented Dec 25, 2020

Edit: I just released Visual Small Basic v1.2. See the readme.

I think small basic needs a mini win forms framework, and a form designer, so in become Visual Small Basic, close to Visual basic 6.
Starting learning programming by graphics is hard as it involves some math. dragging some buttons and textboxes will be more fun, and the tool box can contain some geometric shapes and a timer, which will make many fantastic things.

By the way, where is the repo for the SB desktop IDE?

@VBAndCs
Copy link
Author

VBAndCs commented Jan 10, 2021

@nonkit
This is a proof of concept:
https://github.com/VBAndCs/sVB-Small-Visual-Basic
I haven't added the form designer yet, and the SB.Forms lib is not complete. I am using some pre-compiling to trick the compiler to accept the Object.Method syntax. You can say I've kinda brought the extension methods concept to SB.
Right now, you can load the window design from an Xaml file containing the definition of the canvas and its children, by just calling:
Form.LoadForm(FormaName, XamlPath)
This allows my designer to design advanced windows with controls and shapes with many visual effects, which can be fun for kids, and this will not need any change in SB, and even will not need adding complex methods to the SB.Forms Lib. The designer just saves the design in a Xaml file, and we load it in runtime. We can connect to any object derived from Control and it's Name property is set. I made sure that the SB.Forms lib is ready to do that, by registering name controls in the Controls dictionary, so, all methods can get a reference to these controls by name:
Controls.SetLeft("Form1", "TextBox1", 100)
The designer will generate SB code to provide the names defined in design time, such as:

Form1 = "Form1"  
TextBox1 = "TextBox1"

And to support the dot syntax, the designer will add some notation comment at the beginning of the file. This is the code that will be generated to design a simple calculator:

'#frmCalc{
'    txtNum1: TextBox
'    txtNum2: TextBox
'    lblNum1: Label
'    lblNum2: Label
'    lblResult:Label
'    btnAdd: Button
'    btnSubtract: Button
'    btnMultply: Button
'    btnDivide: Button
'}

frmCalc = "frmCalc"
txtNum1 = "txtNum1"
txtNum2 = "txtNum2"
lblNum1 = "lblNum1"
lblNum2 = "lblNum2"
lblResult = "lblResult"
btnAdd = "btnAdd"
btnSubtract = "btnSubtract"
btnMultply = "btnMultply"
btnDivide = "btnDivide"

Note that I can define the controls without the need of xaml file, (or beside it, if I want to extend the design):

Forms.AddForm(frmCalc)
Form.AddLabel(frmCalc, lblNum1, 20, 20, 65, 40)
lblNum1.Text = "Num1:"
Form.AddTexBox(frmCalc, txtNum1, 90, 20, 100, 40)

Form.AddLabel(frmCalc, lblNum2, 20, 90, 65, 40)
lblNum2.Text = "Num2:"
Form.AddTexBox(frmCalc, txtNum2, 90, 90, 100, 40)

Form.AddButton(frmCalc, btnAdd, 20, 150, 55, 55)
btnAdd.Text = "+"
Control.HandleEvents(frmCalc, btnAdd)
Control.OnMouseLeftUp = btnAdd_Click

Form.AddButton(frmCalc, btnSubtract, 80, 150, 55, 55)
btnSubtract.Text = "-"
Control.HandleEvents(frmCalc, btnSubtract)
Control.OnMouseLeftUp = btnSubtract_Click

Form.AddButton(frmCalc, btnMultply, 140, 150, 55, 55)
btnMultply.Text = "*"
Control.HandleEvents(frmCalc, btnMultply)
Control.OnMouseLeftUp = btnMultply_Click

Form.AddButton(frmCalc, btnDivide, 200, 150, 55, 55)
btnDivide.Text = "/"
Control.HandleEvents(frmCalc, btnDivide)
Control.OnMouseLeftUp = btnDivide_Click

Form.AddLabel(frmCalc, lblResult, 50, 225, 300, 40)
lblResult.Text = "Result: "

TextWindow.WriteLine("")
Form.Show(frmCalc)

All the above code (including the notation), should be separated in a Form1.g.sb file or , if AvalonEdit allows it, it can just simply be hidden in the editor, so, kids don't know anything about. They just write the event handlers code:


'----------------Event Handlers-----------------
Sub btnAdd_Click
  Result = txtNum1.Text + txtNum2.Text
  lblResult.Text = "Result = " + Result
EndSub

Sub btnSubtract_Click
  Result = txtNum1.Text - txtNum2.Text
  lblResult.Text = "Result = " + Result
EndSub

Sub btnMultply_Click
  Result = txtNum1.Text * txtNum2.Text
  lblResult.Text = "Result = " + Result
EndSub

Sub btnDivide_Click
  If txtNum2.Text = "" Or txtNum2.Text = 0 Then
    Result = "Can't divide by zero."
  else
    Result = txtNum1.Text / txtNum2.Text
  endif
  
  lblResult.Text = "Result: " + Result
EndSub

Note that sample is functional now in my modified SB IDE in sVB repo, and you can find it in the samples folder.

Note that I am using a fast dirty parsing code to support the dot syntax, and I think this should be be better written in the compiler parser. I've just proven that it doesn't need big changes in the compiler or runtime. It just a lowering stage that kicks in if the Obj doesn't exist but we know what is the real object is. I can generalize my approach by getting rid of the FormName first param, and supply it as a property, and decorate the SetLeft method with <Extension(nameOf(TextBox))> to tell the compiler that if TextBox1 object in "TextBox.Left = 100" is marked as TextBoxin the notation section, then it can be sent as the first param:TextBox.SetLeft(TextBox1, 100) There is another trick I am using, that TextBox class doesn't contain SetLeft. because it is in the Controls class with all other common methods. I hard coded that, but it can be generalized using an<Extends(NameOf(Control))>` attribute to mark the Textbox and a like classes.
If the compiler supported this, writing lib will be easier without complicating the compiler, but exactly will support a more kid friendly dot syntax (without really dealing with objects. It is still a string!), with more easier event handling model.

The last thing I hope, is that the compiler allow this syntax to have better support for binding object names with their classes:
Using TextBox1 As TextBox
This should replace the TextBox1: TextBox and is not meant to be used by kids, and will not affect the fact that SB is synamic. It is just a code behind to tell the compilet how to deal with dot syntax, and to declare a var named TextBox1 and give him the string value "TextBox1". This will make the generated code cleaner, and parsing dot syntax easier.

I hope you can see the potential of such suggestions. I think it will make SB easier and more powerful.

Irrelevant Note:
I hope SB use Next instead of EndFor. End means to stop not to loop. This is the same kind of mistake VB.NET did when used While ...End While instead of the classical While ... Wend . Loops must indicate that they are looping. Syntax must abbey the human mind semantics used in parsing natural languages, so, programming languages can be easy in learning for kid.
Thanks

@VBAndCs
Copy link
Author

VBAndCs commented Jan 14, 2021

@kmelmon @EdPrice-MSFT @AndrewCook
I add the form designer. It is built on my Diagram designer (I added the source code):
https://github.com/VBAndCs/sVB-Small-Visual-Basic
This is the first look to the form designer:
untitled1

When you switch to the Form code tab, you will see the auto generated SB code, and you can just run it, to see the form in run time.
This is not a complete work. I need a properties window, and a way to visually add event handlers for the selected control. This is a lot of work, and I had no time now.
Note that, the I shouldn't add the auto-generated code to the Active Document. This is a source of all sort of catastrophes, like writing in the wrong document, or destroying any manually added code after the generated code. I'm just giving you the feel and taste of the designer, but actually, the generated code should be buried in a Form1.gsb file.
SB compiler deals only with a single file, so, I will combine the Form1.gsb with the Form1.sb in runtime.
It will be better if SB compiler supports the project concept (this will need to emit multiple modules), and add support for new syntax to avoid my pre-compiling workarounds (as I suggested in a previous post). Put now, I just proved the concept.
Note also that the IDE needs some work to make the toolbar commands support the form designer when it is active. Currently, I left the toolbar in the code tab only as a quick dirty work.

@VBAndCs
Copy link
Author

VBAndCs commented Jan 15, 2021

@nonkit @kmelmon @EdPrice-MSFT @AndrewCook
I added a Color module to ease the use of the color names:

TextBox.BackColor = Color.Red
TextBox1.Text = Color.GetName(TextBox1.BackColor) ' Returns Red

I think this is more kid-friendly than manually typing string color names, or their hex representations.

And I have an idea to ease the use of the Color.GetName method. We can mark methods and properties with the actual type of the primitive. For example: in the Control module, we can define the GetBackColor like this:

<ReturnType(NameOf(Color))>
    Public Function GetBackColor(formName As Primitive, controlName As Primitive) As Primitive

End Function

So, the compiler now knows that ther return value related to the color module, and hence can allow this syntax:
TextBox1.Text = TextBox1.BackColor.Name

BackColor marked as Color, so, this syntax says: Value.ColorMethodName and can be translated to: 'Color.ColorMethodName(Value.). If ColorMethodNamedoesn't exist, we can try GetColorMethodName as it can be a property get accessor. So, We will have:TextBox1.Text = Color.GetName(TextBox1.BackColor)It is easy to implement at the parser (not that easy in my pre-compiling stage), and the expression:TextBox1.Text = TextBox1.BackColor.Name is definitely easier and more readable. thenTextBox1.Text = Color.GetName(TextBox1.BackColor)`
This idea can be generally applied to make using external libraries a fun :)
Note that With current Small basic, this is the only allowed syntax:

Control.SetBackColor(Form1, TextBox1, Color.Red)
Control.SetText(Form1, TextBox1, Color.GetName(Control.GetBackColor(Form1, TextBox1)) 

Which makes using liberties too hard.
I hope we can work together to deliver a more powerful yet easier Small Basic.
Thanks.

@VBAndCs
Copy link
Author

VBAndCs commented Jan 15, 2021

Interesting sample: Use the form designer to add a textBox and a button, then add this code after the generated SB code:

Button1.HandleEvents()
Control.OnMouseLeftUp = Click
TextBox1.BackColor = Color.Red
Trans = 0

Sub Click
  Trans = Trans + 10
  TextBox1.BackColor = Color.SetTransparency(Color.Red, Trans)
EndSub

Things will be a bit nicer if we allow the syntax (the way I explained b4):
TextBox1.BackColor = Color.Red.SetTransparency(Trans)

@nonkit
Copy link
Member

nonkit commented Feb 3, 2021

Hi @VBAndCs, this is just for your information. LitDev's Small Basic Prime has Shapes Editor that we can also create controls visually.

@VBAndCs
Copy link
Author

VBAndCs commented Jul 9, 2021

@nonkit
I saw small basic Prim but it is an overkill IDE fir a language for kids with limited compiler. The IDE is crowdy, intimidating, and hard to use. My goad it to make sb simpler and enjoyable.
I did appky many of my ideas on my sVB version. Now I can:
untitled2

  • Write Form1.Text = "test" and "Me.Text = "test""
  • Same for controls.
  • With intellisense and docuamntaion help support.
  • the designer adds event handlers for rhe form and controls in vb6 style. the kid just sees
    Sub Button1_OnClick
    
    End Sub
    
    
  • you can event manually write this conventional handler name and the IDE will recognize it as a handler. The IDE fixes any broken event handlers so no error will occur after deleting or changing the sub name.
  • All the verbose sb code that makes this work is hidden in a code behind file. This is the code behind for the form in the picture:
'#Form1{
'    TextBox1: TextBox
'    Button1: Button
'}

Me = "Form1"
TextBox1 = "TextBox1"
Button1 = "Button1"
True = 1
False = 0
Forms.AppPath = "UnSaved\Project1\Form1"
Form1 = Forms.LoadForm("Form1", "Form1.xaml")
Control.SetWidth(Form1, Form1, 700)
Control.SetHeight(Form1, Form1, 500)
Form.Show(Form1)

'#Events{
'    Button1: OnClick
'}

' Button1 Events:
Control.HandleEvents(Form1, Button1)
Control.OnClick = Button1_OnClick



  • The IDE auto-completes code blocks like If Then EndIf, and maintains correct indentations.
  • By the way, I fixed sb indention issues (like adding more indention b4 EndIf when pressing enter at the end of line) you can make use of the correction is sb. Look here

ToDo:

  • I will add the default event handler when double clicking the control on the designer. I will write it today.
  • I will allow changing the control name and text by the designer
  • I will complete the code of the SB.WinFotms lib. I will mot complicate that. Just enough controls and properties for leaning and crating fun apps.

You can say that sVB 1.0 will be ready for kids in a few days.
Feel free to reuse any parts of it in SB.
Thanks.

@VBAndCs
Copy link
Author

VBAndCs commented Jul 11, 2021

sVB is a release candidate now.
By the way, isolved some issues in my the indentation as i missed some else nad elseif, and it is perfect now.
https://github.com/VBAndCs/sVB-Small-Visual-Basic/blob/16804e85368a66b6b01f30d7e3f110ba0db676b7/LangServices/IndentationKeyboardFilter.vb#L43

@VBAndCs VBAndCs changed the title [Proposal] Visual Small Basic Announcing Visual Small Basic Jul 28, 2021
@VBAndCs
Copy link
Author

VBAndCs commented Jul 28, 2021

I just published vSB 1.0-final. The form designer has only 4 controls now but it will have more soon.

Untitled

I also improved the SB compiler and added new code features:

  1. Support array initializers:

You can use the {} to set multiple elements to the array at once:

x = {1, 2, 3}

Nested initializers are also supported when you deal with multi-dimensional arrays:

y = {"a", "b", {1, 2, 3}}

You can also use vars inside the initializer, so, the above code can be rewritten as:

y = {"a", "b", x}

And you can send an initializer as a param to a function:

TextWindow.WriteLine({"Adam", 11, "Succeeded"})
  1. For Next and While Wend:

SB uses EndFor and EndWhile to close For and While blocks respectively. This is still supported in sVB but I allowed also to use Next to close For and Wend to close While, as they are used in VB6. I encourage you to use Next and Wend, as they give the meaning of repeating and circulating over the loop. End gives the meaning of finishing and exiting, so, it is suitable in EndIf and EndSub, but confusing in EndFor and EndWhile, as they can imply that the loop finishes here, not just the block ends here!

  1. You can use ExitLoop to exit For and While loops, and ContinueLoop to skip the current iteration and jump back to the beginning of the loop body to continue the next iteration in for loop. Be aware that unlike For, while doesn't have an auto-incremented counter, so be sure you write the suitable code to update the variable that while condition depends on before using ContinueLoop inside the while block, otherwise you may end up stuck with an infinite loop.
    In the case of nested 2 loops of any kind, you can exit the outer loop by using ExitLoop -. You can add more - signs to exit up levels loops in case you have 3 or 4 nested loops, or just use ExitLoop * to exit all nested loops at once. The same rules applies to ContinueLoop if you want to use it to cointinue outer loops.

  2. You can use Me to refer to the current Form.

  3. True and False are keywords of sVB.

  4. Subroutines can have parameters now:

Sub Print(Name, Value)
   TextWindow.WriteLine("Name=" + Name + ", Value=" + Value)
EndSub

And call this sub like this:

  Print("Distance", 120)

Note that you can use Return inside the sub body to exit the sub immediately.

  1. sVB can define functions now. You can supply params to get the fyunction input and use Return to return the function output.
Function Sum(x, y)
    Return x + Y
EndFunction

And you can use it like this:

x = Sum(1, 2)
  1. SB doesn't have variable scope, as all variables are considered global, and you can define them in any place in the file and use them from any other place in the file (up or down). sVB has cleaned this mess, which is a break change that can prevent some SB code from running probably in sVB, but it is a necessary step to make the kid organize his code and write clean code. This is also necessary to make sub and function params work correctly, and allow you to use recursive subs and functions. The mew scope rules are:
  • Sub and function params are local, and hides any global vars with the same names.
  • The For loop counter(iterator) in local and hodes any global var with the same name.
  • Any var defined inside the sub or the function is local unless there is a global var with the same name is defined above of the sub function. If the global var is defined below, then the local var will hide it.

So, as a good practice:

  • Define all global vars at the very top pf the file.
  • Give global vars a prefix (such as g_) to avoid any conflictions with local vars.
  • Don't use global vars unless there is no other solution, instead pass values to subs and functions through params, and receive values from functions through their return values.
  1. The editor auto completes If, For, While, and Sub blocks just after writing a space after them.

  2. The editor has a perfect auto-indentation.

@VBAndCs
Copy link
Author

VBAndCs commented Aug 7, 2021

I just released Visual Small Basic v1.2
You can change the form shape by allowing transparency:
3333

2222

And I made a Cars game sample. It is just a prototype as I want kids to complete it themselves.

222d

@VBAndCs
Copy link
Author

VBAndCs commented Aug 7, 2021

One simplification rule I added to vSB is to treat any variable name that starts or ends with a control name as an object of this control. In the Cars game, you can see code like this:

carLabel = car[c_Label]
w = screenWidth - carLabel.Width

carLabel is treated as a Label object, so, sVB provides auto completion after writing carLabel. and you can use the Label module extension methods as properties, where sVB precompiler will convert the second line in the above code to:
w = screenWidth - Label.GetWidth(Me, carLabel)
If fact, I am thinking to do more with naming convention, as supporting structures in the form:

carStruct.Label = Me.AddLabel("test", 0, 0, 100, 200)
carLabel = carStruct.Label

Which will be lowered to:

car["Label"] = Me.AddLabel("test", 0, 0, 100, 200)
carLabel = car["Label"]

This will make it work like dynamic in C# and VB.NET :)
The benefit of this is the auto-completion support when writing the Keys\Properties names.

@VBAndCs
Copy link
Author

VBAndCs commented Aug 8, 2021

Done :)
7

Note that MyPos2Data inherits properties from MyPosData, Pos2Data and PosData, because their names are contained in its name. This makes writing code easier and faster with auto completion.

@VBAndCs
Copy link
Author

VBAndCs commented Aug 9, 2022

sVB now allows using the dictionary lockup operator (!) to define dynamic properties:

pos!X = 100
pos!Y = 200

It also allows using _ to split lines into multi sub lines. But the _ is not needed after some symbols like ,, +, -, (, or, and... etc.
You can add comments at each sub line:

Sub Add (
      n1,  ' The first number
      n2   ' The second number
   )
 
End sub

sVB editor formats such lines very well, and also applies some pretty listing to adjust spaces between tokens to format the code as expected.
Enjoy: https://github.com/VBAndCs/sVB-Small-Visual-Basic/releases/tag/v1.4

@VBAndCs
Copy link
Author

VBAndCs commented Oct 9, 2022

sVB 2.0 is released. It can create a multi form project with a common Global .sb module where you can declare global variables and subroutines that can be used from any form in the project via the Global. prefix, such as Globla.MyFuncution().
The Show Dialogs app in the samples folder shows a good example on using the global file with three forms. It crates the famous VB MsgBox and InputBox functions to show a message Box and an Input Box.
sVB is now where I planned for it two years ago and I thinks sVB is now the smooth transitional stage between Small Basic and VB .NET!
I hope kids and beginners enjoy it and find it useful.
https://github.com/VBAndCs/sVB-Small-Visual-Basic/releases/tag/v2.0

@VBAndCs
Copy link
Author

VBAndCs commented Oct 14, 2022

sVB v2.3 can create a code library!
For the first time, it is now possible to use an sVB app as a library! Follow these instructions:

  1. Create a sVB project with a global file. Choose a suitable name for the folder that you save the project files to (such as MyLib), because the name of this folder will be the name of your library. Don't use spaces nor symbols.
  2. Add variables, subroutines, and functions to the global files. These are the members that you can access from the lib.
  3. Add comments for each variable, subroutine, parameter, and return value. These comments will be saved as the documentation for your lib, and will be shown in popup help in sVB when you use this lib.
  4. You can also add a comment at the beginning of the global file, to be used as the documentation for the Lib Type.
  5. The project can contain as many forms as you need, but you must choose unique names when saving them to the project folder. Form1.xaml, Form2.xaml and Form3.xaml can cause troubles later, so, if you must, name them MyLib_Form1.xaml, MyLib_Form2.xaml and MyLib_Form3.xaml. Don't rename the files manually from windows explorer, and use the sVB project explorer to rename them, to do necessary changes to the .sb.gen file.
  6. Run the project to create the exe file in the Bin folder in the project folder.
  7. Now you can copy the Bin folder and paste in the sVB\Bin\Lib folder, then rename it to the name of your lib such as MyLib in this example. The name of this folder is not important, but Bin is not a suitable name, and of course you can't add tow libraries with folders named Bin because they will be merged, which can cause troubles later!
  8. Restart sVB, and in the code editor write the name of your library such as MyLib, then press dot. The auto completion list will show the members you declared in the global file and can use them. If you add comments to those members, you will get help info about them while typing.
    It is so simple. You can apply it on the Show Dialogs project in samples folder, but I advice to change the folder name to Dialogs instead, so, you can use this library like this:
Name = Dialogs.InputBox("Enter your name")

So, now you can create reusable code, and write your own libraries for sVB. In the past, this was available only by using C# and VB.NET to create SB and sVB libraries!
Have fun.

@VBAndCs
Copy link
Author

VBAndCs commented Nov 4, 2022

Untitled2

sVB v2.5 is ready to create productive desktop apps:

  1. The toolbox now contains four new controls:
  • ProgressBar, ScrollBar and Slider: These bars are horizontal only, but you can use the rotate thumb of the control on the designer to rotate them to become vertical! For more info, see the Progress and Slider Color Composer apps in the samples folder.
  • ToggleButton: This control can be checked or unchecked but it seems like a button that appears clicked or un-clicked. See the Toggle Buttons app in the samples folder.
  1. You can add many timers to the form, by calling the Form.AddTimer Method. Small Basic library already contains the Timer object, but it is only one timer, and it makes code harder to make it handle different actions in different intervals. Besides, it may not work properly with forms and controls, and of course it will be missy if you try to use this single timer to handle different actions in many forms. So, to make things easier, you can now add as many timers as you need to each form!
    For example, the Stop Watch app in the samples folder uses two timers, one to update the current date and time displayed on the form title bar, and the other one to count the elapsed time for the stop watch.

  2. You can show the open file and save file dialogs to the user by calling File.OpenFileDialog and File.SaveFileDialog methods. You must send the extensions filter to these methods, which controls the types of files that the browser will show to the user. You can use the standard .NET filter string like "Text Files|*.txt;*.rtf|Docs|*.doc", or you can send the filter as an array like

fileName = File.OpenFileDialog ({
   {"Text Files", "txt", "rtf"},
   {"Docs", "doc"}
})

For an example, see how these methods are used to open and save files in the sVB notepad app in the samples folder.

  1. You can show the font dialog to let the user choose font properties, by calling the Desktop.ShowFontDialog method. This method empty string "" if the user canceled the operation, otherwise it returns an array containing the font properties under the keys Name, Size, Bold, Italic, Underlined and Color, so you can use these keys as dynamic properties:
Font = Desktop.ShowFontDialog(Me.Font)
Me.FontName = Font!Name
Me.FontSize = Font!Size

In the above example, you see that the ShowFontDialog has a parameter that receives an array containing the initial font properties. To make this easy, each control now has a Font property that returns an array with the font properties. You can also use this property to change font properties of the control in one step:

font = Desktop.ShowFontDialog(Me.Font)
If font <>"" Then
   Me.Font = font
EndIf

And to make this even easier, each control has a ChooseFont methods that shows the font dialog and sets its result to the controls Font property, so the above 4 lines can be replaced with this single line (or in fact these two words!):

Me.ChooseFont()
  1. If you want to crate a custom font dialog, you will need to know the font names defined on the user's system. In such case, use the Desktop.FontNames property to get an array containing these font names.
    For a sample on how to create a custom font dialog, see the FrmOps in the sVB notepad app in the samples folder.

  2. You can show the color dialog to allow the user to choose a color, by calling the Color.ShowDialog method. And for simplicity, each control has the ChooseForeColor and ChooseBackColor methods to show the dialog and change the control fore and back colors directly.

  3. You can now crate a main menu for the form by using the Form.AddMainMenu method, that returns the main menu object, which you can use it's AddItem method to add menu items.
    For more info, see how the menus are defined in the formMain in the sVB notepad in the samples folder.

  4. You can show a child form that it owened by a parent form by calling the Form.ShowChildForm method.
    A child form will alowys appear on top of its parent form even when you activate the parent form. If you hide or minimize the parent form, its child will be hideen with it, and when you show the parent form again, its child will appear again.
    For example, this is how the FormMain shows the frmFind as a child form in the sVB notepad in the samples folder"

Me.ShowChildForm("FrmFind", TxtEditor)

Ther first argument is the name of the child form (and the auto completion list will offer the names of the forms for you), and the second param is an extra data that will be passed to the ArgsArr property in the child form.

  1. You can change the style of the form and controls by loading styles from a recource dictionary. This is an advanced topic, that needs knowlage about XAML and WPF, but it always you to make use of syles and thems defiend for WPF, UWP or WinUI3 to make a beautiful design, and change how controls look and even work!
    All you need is to have a Resource dictonary in a Xaml file, then use these two methods to load it:
  • Control.SetRecourceDictionary: send the xaml file path to this method to load stryles from it into the control and its child controls. This means that if you called it from a form. the styles will affect all target controls if exists on it. Note that this method needs that styles have no keys. Styles with names (keys) will not be aplied to controls here.
  • Control. SetStyle: it is similal to the previous method, but it has a second parameter that recives the name (key) of the style. It is useful when you want to apply a style on only one control.
    Note that if the style have no name, you can call SetRecourceDictionary from this control instead to apply the style on it, but this can also apply another styles on the controls if the resource dictionary has many styles targetting the same control type.
    For mor info, see the Custom Styles app in the samples folder. the tow files RoundCorner.style and RoundCorner2.style are in fact XAML files, but I changed there extensions from .xaml to .style not to be cinfused with form design files. But if you used .xaml extension it will also work.
  1. If you want something easier, you can change the Button and ToggleButton appearenace by setting the Flat property to True. This will help you use theem as a toolbar buttons by butting a label under them, as you can see in the Toggle Buttons app in the samples folder.

  2. Use Form.Icon property to set the icon that appears on the form title bar.

  3. Use the Program.SaveSettings method to save a value to the windows registry, and use the Program.GetSettings method to read this value back from the registry.

Create an external library for sVB:

sVB can use external libraries created for Small Basic (like LitDev). Just insert those libraries dll files in the Lib folder of sVB and you are ready to go!
This means you can also write such libraries (using C# or VB.NET), to add new functionality that is not available in sVB. To do this, you should follow these rules:
https://social.technet.microsoft.com/wiki/contents/articles/53826.small-basic-extensions.aspx
The above rules will allow you to create a library for Small Basic, which also will work with sVB. But you can create a library for sVB only, by targetting .NET Framework 4.8 and refrencing the SmallVisualBasicLibrary.dll file (found in sVB\bin folder) instead of SmallBasicLibrary.dll, and you can mark your functions and properties with the ReturnValueTypeAttribute to specify the return value type, to allow sVB to infer the type of expressions that use these functions and properties. For example:

<ReturnValueType(VariableType.Double)>
Public Shared Function Sum(x As Primitive, y As primitive) As Primitive
     Return x + y
End Function

For more info, see the DemoLib project at the samples folder. It is a VB.NET project that crates a DemoLib.dll in its bin\release folder, which I copied to the sVB\bin\lib folder so you can try it with DemoLibSample app in the samoles folder.

Now we can announce sVB as a mature productive dssktop programming language, and you can use it to build interesting apps. Have fun.

@VBAndCs
Copy link
Author

VBAndCs commented Nov 12, 2022

Write and run unit tests in sVB v2.6!

sVB makes it easy to write unit tests. Every form can define test functions among its normal function, and you can run them all easily just by calling the Form.RunTests() function, which will run the tests, and display the results on the form on a textbox named "txtTest". If the form doesn't contain a text with this name, it will be added in runtime, and this will not affect your form design when you run your app normally (not in test mode).
The test function must follow these rules, to be recognized by the RunTests method:

  1. Its name must start with Test_, like Test_FindNames.
  2. It must be a function not a sub, and it can't have any parameters.
  3. The function return value should be a string containing the test result like "passed" or "failed". It is better to mention the test name in the result.

The UnitTest Library:

To make things more easier, sVB samples folder contains the UnitTest project, which is used to create the UnitTest Library that is included in the sVB\Bin\Lib folder, so you can use it in your projects.
The library has these important methods:

  1. UnitTest.AssertEqual:
    Use this method to perform your tests. It receives three arguments:
  • The actual value that you got from executing the
    code being tested.
  • The expected value, that is the correct value that you should get when executing the code being tested.
  • The name of the test to include in the result.
    The AssertEqual method compares the actual value to the expected value And this method returns a string message, saying what is the result of the test:
  • If the two values are equal, it returns the message: "[Test Name] Passed".
  • If the two values are equal, this indicates that the test has failed, so, this methods returns the message: "[Test Name] Failed", and appends the actual and expected values to the message, so you can see what went wrong.
    Note that the both actual and expected values can be two single values, or two arrays. Using array of values allows you to do many small tests in the same test function. You should only do this if all these small tests are related and do the same test but with different values to cover all possible situations.

For an example on how to use this method, see the tests written in the UnitTest Sample app in the samples folder.

  1. UnitTest.RunAllTests:
    This method runs all the tests in all forms of the project. It has only one parameter, that receives the textbox you want to use to show the test results. This allows you to add a test form to your project, add a textbox on it, then add this line at the global section of the form code:
UnitTest.RunAllTests(TextBox1)

Now when you select the test form and run the project, all the tests in all forms of the project will be run, and you will see the error report (if any) in the textbox, so you can fix any errors.
Then, when you want to run your app normally, just select the main form and run the project!
By this simple way, you can switch easily between test mode and normal mode!
For an example on how to use this method, see the tests written in the UnitTest Sample app in the samples folder.

  1. UnitTest.RunFormTests:
    This method is just an alias to the Form.RunTests method. It is better to keep all unit test method together.
    The RunFormTests has one parameter that receives the name of the form you want to test. This makes it capable of running the form tests from another form or from the global module.

Note that I kept the UnitTest lib out of the Small Visual Basic Library, so you can modify its sVB source code, in case you want to add more Assert methods, or want to change the format of the result message.
So, have fun writing test for your code. Unit tests makes it easy to discover hidden errors, and you should run them each time you make changes to your code, as such changes can break some functionality of you app, so running the tests can make sure that every thing is working as expected, or there are some issues that needs to be fixed, which of course are related to the latest changes you have made.
This is why I am using the UnitTest lib right now to write a test project for Small Visual Basic Library, which discovers some small hidden bugs in the sVB library and the compiler, and I fixed them in this version.
In fact, what made me walk this path, is that I was adding example code snippets to the sVB reference book (still in progress), when I realized these snippets can be reused to test the sVB library, hence I crated the UnitTest Library and the sVB Tests project (still in progress too).

@VBAndCs
Copy link
Author

VBAndCs commented May 14, 2023

sVB 2.8.1 is released, and this is its installer. It contains the sVB reference book, which is also published on google drive.

1111

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants