Πέμπτη, 12 Οκτωβρίου 2017

Event-Driven Programming in M2000

Events can be used in M2000.

1) Event object

\\ Event-Driven Programming
Event alfa {
      Read &K, z
      function {
            Print K, z
      }
}

Group Beta {
      Private:
      K=10
      Public:
      Function Delegate1 (&M, N) {
            ' this is an event handler
            '  called with returning something
           If .K>0 then .K-- : M+=1+N
      }
      Group GetK {
            value {
                  link parent K to K
                  =K
            }
      }
}
Delta=Beta \\ we get a copy
\\Event alfa new &Beta.Delegate1()
\\ Now  we import references to alfa event
Event alfa new &Beta.Delegate1(), &Beta.Delegate1(), &Delta.Delegate1()
z=0
\\ now we can call event 10 times.
For i=1 to 10 : Call Event alfa, &z, i : Next i
Print z, Beta.GetK, Delta.GetK \\ 105, 0, 0


2) Gui Events
This example can work in windows and in Ubuntu Linux using Wine. Also in this example added a thread as a background task. So execution stop at line A$=Get$ where we stop for getting a key from keyboard (on console), but thread running, and event handlers work in background too. Gui events fired from form Simple, and thread fired from a clock setting on OS, which call internal task manager. Task Manager utilize two lists, one list is for running tasks and one list for waiting tasks. By default Thread.Plan is Sequential, but we can use Concurrent plan too (must change before threads used)

(add two statemends to set fonts to support character  )
We can leave these lines as is, or we canchange font name, with something else, or fontname$  a read only variable about console fontname.


Declare Simple Form
With Simple, "Title" As myTitle$
Method Simple, "FontAttr", "Arial Unicode MS", 16
Method Simple, "CtrlFontAttr", "Arial Unicode MS", 12

\\ make window, not show yet
Layer Simple {
      Linespace 60
      Font "Arial Black"
      Window 16, 8000,6000
      Cls 1,0
      Cursor 0, height div 2
      Report 2,"Hello World"
}
\\ now put a ListBox
Declare Listbox1 Listbox Form Simple
Method Listbox1, "move", 1000,1000,6000,4000
\\ and fill with some data
With ListBox1,"Text",{London
                                    Paris
                                    Athens
                                    Rome
                                    Tirana
                                    Nicosia
                                    Brussels
                                    Copenhagen
                                    Berlin
                                    Dublin
                                    Luxembourg
                                    }
\\ and set some properties, and some of them are bind to objects that are properties to objects.
\\ also when we call a method, internal a resolved done in first time, so next time a method call will be faster.
With Listbox1, "transparent", True , "ListIndex" As ListIndex, "ListCount" As ListCount
With Listbox1, "Find" As Find(),  "List" As List$()
\\ make simple sizable form (units for forms are in twips)
With Simple,"Sizable", True,"SizerWidth",90
\\ now these are the event handlers
\\ event handlers can see anything defined in parent module
\\ for this reason for &rgb we need a Read New (so a new rgb prepared before a reference assign to it)
\\ any variable can get a reference to other variable once, at defining stage.
Function Simple.Unload {
      Keyboard "!"   \\ like press !
}
Function listbox1.Color {
      Read New &rgb
            rgb=#FF7700
}
Function Listbox1.DblClick {
            Read Where
            if Right$(List$(Where),1)="✓" then {
                  List$(Where)=leftPart$(List$(Where)+" "," ")
            } else {
                  List$(Where)=leftPart$(List$(Where)+" "," ")+" ✓"
            }
            Method Listbox1,"Refresh"
            Mytitle$= List$(Where)
}
Function simple.click {
            If ListIndex>=0 Then {
                  local K$=List$(ListIndex), i
                  Method listbox1,"Sort"
                  ListIndex=Find(K$)
                  Layer {
                        \\ we print to standard cosnole layer
                        Print ">>", control$
                  }
            } Else Method Listbox1,"Sort"
}
Function Simple.Resize {
      Layer Simple {
            Mode 16
            Cls 1,0
            Cursor 0, height div 2
            Report 2,"Hello World"
            Method Listbox1,"Refresh"
      }
      \\ we put a refresh to console

      Layer { Refresh}
}
\\ now we want to show (without modal showing)
Method Simple, "Show"
\\ We can put a background task (a thread), triggering each 100 mSec
Thread {
      Print tick \\ tick is thread manager timer
} as K interval 100
a$=Key$ \\ no loop just wait a key, in console only
Threads Erase
Declare Simple Nothing