About this tutorial

In the course of the recent years, I have done many smaller and some big applications. In this years i learned a lot and optimized my knowlege. If i compare old source codes with the current ones, i see many differences.

At the beginning of learning programming in yab my focus are at the functionalitiy of my programs. There is still not paid as much attention to the appearance and background processes. This thinking changes with time. If you always do the same Programming work, you comes to the point there you take all ready codes from your old projects. If you found a way to optimize a process, it quickly be a part of your everyday programming.

Today there are several queries in my programs for program execution. I hate it if my program does not run, because anything is missing. If I, for example, certain need directories or files for my program, so I check them before. All that is missing will be created or the user will be informed.

In this tutorial I would like to share this experience with all People who have interest into it.
 

Index

 


 

Pay attention to consistently Design

The german say about eating "The eye eat with you", so this is also true on the design of your Programs. If your program is easy to use and have a nice and clear design, the user will love it. However, is there chaos into your program the user does not like it. This affects the choice of color, font, design of buttons, Text areas, etc.

However, it is important that your design does not destroy a logical and friendly user interface. It is not always easy to find here the right way.

Often they are little things who takes the biggest effect. I use for my part, for example, almost not the yab modules inserted label areas. I use DRAW TEXT and add then the needed yab module behind it.

DRAW TEXT 10,25, "Name: ", "View"
TEXTCONTROL 110,7 TO 320,17, "TC:Name", "", "", "View"

Thus, the position of the TEXTCONTROL is not dependent on the preceding text. So you can place more textcontrol under each over at the same optical position.


back to Index


 

No outsourcing in libraries during programming

Normally, you should always program so that you must not touch anything twice. This saves time and prevents eternal change the existing code in continue programming. But this is always easier said than done because often force a new program options to change existing code.

Therefore, it is not always advisable to outsource anything and everything into libraries during the programming process. You will lost many spare time at changing between opened files.

If a program or a part of a program is allready finished you can outsource them without any problem.

But ultimately, everyone has to decide for themselves how is the best to handle is. For me it works fine to add behind program parts who belong together a comment to jump through the code using the search option ("Alt + g").

Button 10,20 to 110,40, "Sort", "Sorting", "View"         //sorting

case "Sort|"         //sorting

Sub Sorting()         //sorting


back to Index


 

user friendly program

  • What is really important for the user?
  • How does the user will get along with the program?
  • Do i need a documentation or does the program descript them self?

These are questions you should always ask yourself. Never decide there it looks like you see it by yourself because a developer have his own logic which is not always transferable to the user.


back to Index


 

A good basic building

With a good basic building is meant that you need to use a good framework for your projects. It does not make sense to starting every time again from scratch. Over the years, my framework changed a little bit. Not much really but it has proven itself. With my framework I have been able to realize every project, so I can only recommend this:

#!/boot/home/config/bin/yab

REM Name of Program
REM Developer
REM Build Version / Date
REM yab Version

if (peek("isbound")) then
        ProgramFolder$ = peek$("directory")
else
        ProgramFolder$ = system$("pwd")
        ProgramFolder$ = left$(ProgramFolder$, len(ProgramFolder$)-1)
fi

//Program info

screenWidth = peek("desktopwidth")
screenHeight = peek("desktopheight")

//Main Window

dim part$(1)

inloop = true

while(inloop)

        msg$ = message$

        if (split(msg$, part$(), ":|") > 2) then
                PartOne$=part$(1)
                PartTwo$ = part$(2)
                PartThree$ = part$(3)
        fi
        if (split(msg$, part$(), ":|") > 3) then
                PartFour$ = part$(4)
        fi
        if (msg$ <> "") print msg$

        switch msg$

        //Cases

        default:

        end switch

        //Special Cases

        if(window count<1) inloop = false

        sleep 0.05

wend

//Subroutines

sub IfExists(filename$)
        return not system("test -e "+filename$)
end sub



back to Index


 

Getting the screen resolution

A determine the screen resolution can have many advantages. For example, you can place the program window in the middle of the screen. Another possible option is to change the program window to the monitor-specific options (fullscreen...).

To determine the screen size is very simple and requires only two rows of your program code:

screen_width = peek("desktopwidth")
screen_height = peek("desktopheight")


The variable names screen_width and screen_height are no protected parts of yab, you can name them as you like. This number variables can be used for each size specification of the program window, or course of any other window. The simplest solution is to divide the screen variable number by two and then to deduct half the desired window size. The same for the other site, but here you add the half size of the window.

window open screen_width/2-300, screen_height/2-200 to screen_width/2+300, screen_height/2+200, "Main Window", "Example program"

So your window have a size of 600x400 pixel.

back to Index


 

Make GUI Elemente names splitable

To make a query of an operation of the application more clearly and to define a GUI element more precisely, make the name of it splitable.

If, for example, you give a button a more specific name, who declare the button as is, you can check all button outputs using one case command:

Definition of the button:

BUTTON x1,y1 TO x2 ,y2, "BT:Name" , Label$, View$


Here the Case:

case "BT:"+PartTwo$+"|"
        if(PartTwo$="Name1")then
                //Aktion bei Button 1
        elseif(PartTwo$="Name2")then
                //Aktion bei Button 2
        endif
        break

The same for all GUI elements. So you would then have a case- query for each GUI element. Of course, this can also be confusing at the end, all depends on how many query of this type are necessary. For my part i accepted this way and are very satisfied.

Here is a table with my shortcuts for my GUI elements:

Shortcut GUI Element
AL Alert
BT Button / Button Image
BV Boxview
CV Canvas
CD Calendar
XB Checkbox
CB Columnbox
DB Dropbox
FP Filepanel
LB Listbox
RB Radiobutton
SL Slider
XV Splitview
SV Stackview
SB Statusbar
TV Tabview
TE Textedit
TC Textcontrol
TB Treebox
VI View
WD Window


Of course you can divide the name of a GUI element more than once. Basically, as often as is necessary and reasonable.


back to Index


 

Check for presence of directories and files

If you use fixed directories or external programs, this should be checked in advance. Even if you release these files and/or directories with the program, check them first because you never know that was changed into your system.

Example: When the program starts, a configuration file is read, which contains all the important information for the application. If these file are not available the application does not run, it crashes. The user of the application does not see any information why this happened, because the program is apparently just ended.

Now there are several ways to solve this. For example, you could show an info window with an error message, to inform that an error has occurred.
The better way is, would the program creates the configuration file automatically by himself it the file are not available. For this reason, I never release a program with configuration file anymore, i let check for it and generate them automatically. So it does not matter whether it exists or not, because even if a configuration file, for whatever reason, should not be present at once, a default configuration file is created.

The yabIDE give us a solution. It use a if query with a subroutine and the terminal program test to looking for a file:

filename$="/Path/to/file/you/are/looking/for or folder"

If(IfExists$(filename$))then
else
  Here the program code if the file or folder does not existis wurde
endif


And the subourine out of the main loop:

sub IfExists(filename$)
  return not system("test -e "+filename$)
end sub


Now, you could probably say what happens if the terminal test command at once deleted in Haiku? Well then you should, if you want to get safe, release them with your program. want, also check this or even better with the program


back to Index


 

Use statusbar correctly

When do you need a statusbar?

Actually, whenever you want to show the user a process. It is important that the user does not get the feeling that the program has stopped (an error occurred).

You should fill up the statusbar with 5 to 10 percent, before the process is started. After that, the process can go through normaly (of course, with time between Updating the status bar).

At the end of process the statusbar should be filled 100 percent minimum 2 - 3 seconds, so the user can see that the process are ended (if you remove or change it).

The user should always get enough time to realize when a process starts and ends.


back to Index


 

Use fixed fonts

In an attempt to get a consistently view of a program, plays the font a major role. If this is not defined, the default system font used (changeable by the user). This can destroy your program design. For example, a text in front of a picture can be bigger, stronger or larger as on your development computer, so the text does not ends before the picture, it ends into the picture.

yab Commands: Fonts


back to Index


 

Reducing lines

How larger a program code is, you comes to a point to make the source code smaler and more clearer.

Here are a few ways to reduce the code:

Cases

In the cases you can, for example, put together several case functions into one query (they need to do the same thing). You only need to write them after the other and ending it with one break.

case "Example-App:_QuitRequested|"
case "Example-App:Program:Quit|"
  window close "Example-App"
  break


Queries

When reading from files and directories you can reduce many lines. You only need to outsource them into a sub-routine and then call it to read out a file or directory. Then you only need to use every time the same varialbes.

This example shows how to read out a directory using the same sub-routine and save the output information i a variable.

We add into the variable target$ the directory-path. Then we call the sub-routine. In the sub-routine we read out the entries of the directory (target$) using the terminal program ls. Into the Array SplitProfile$(1) we store all entries we get at spitting the program message (msg$) separated by /n. The example displays all entries.

target$="/boot/home/config/myprogram/profiles"
readtarget()

 

sub readtarget()
  filename$=system$("ls -G -1 "+target$)
    dim SplitProfiles$(1)
      pf=0
      pfa=0
      pf = split(filename$, SplitProfiles$(), "\n")
      for pfa = 1 to pf
          print SplitProfiles$(pfa)
      next pfa
end sub


back to Index


 

Tutorial by Christian Albrecht (Lelldorin) Juli 2011
Translated by Christian Albrecht (Lelldorin) May 2013
Made available by the BeSly the Haiku knowledge base.