Πέμπτη 25 Μαΐου 2017

Αναθεώρηση 5 (Έκδοση 8.8)

Ενώ έγραψα ότι δεν θα προχωρήσω τη γλώσσα. τελικά οι ιδέες δεν με αφήνουν! Το παρακάτω είναι κάπως "μπέρδεμα", αλλά γίνεται!
Κανονικά ένα τμήμα κώδικα (με όνομα δηλαδή) δεν μπορεί να καλέσει άλλο τμήμα που βρίσκεται σε άλλο τμήμα. Μπορεί να καλεί μόνο τα δικά του, που έχει δημιουργήσει (όπως λέει ο κώδικας), ή ό,τι είναι γενικό, που μπορεί να ορίστηκε σε άλλο τμήμα που καλεί το συγκεκριμένο ή να είναι απλά γενικό επειδή είναι στην αρχική λίστα τμημάτων - ή όπως το ονομάζω στο επίπεδο 0.

Η ιδέα ήταν να μπορώ πριν καλέσω ένα τμήμα, το οποίο έχει δικά του τμήματα, και τα δημιουργεί στην εκτέλεση), να του δώσω στη κλήση άλλα τμήματα "αντικαταστάτες" αυτών που "θα" δημιουργήσει!
Ίσχυε ότι αν ένα τμήμα οριστεί δυο φορές σε ένα τμήμα τότε ο δεύτερος ορισμός ισχύει (στην ουσία ο κώδικας του πρώτου εξαφανίζεται, και στη θέση του έρχεται ο νέος κώδικας)
Η ιδέα ήταν απλή: Θα βάλω σε κάθε τμήμα μια "σημαία" που θα λέει "δεν αλλάζω κώδικα", έτσι ώστε σε "επόμενη" αλλαγή να μην επιδέχεται νέο κώδικα.
Αυτό λοιπόν θα μπορούσε να γίνει αν ήδη πριν τον πρώτο ορισμό ενός τμήματος, με κάποιο τρόπο υπήρχε το τμήμα!

Ένα τμήμα Α δεν μπορεί να καλέσει τον εαυτό του, με τον κανονικό τρόπο κλήσης, με το όνομά του μόνο. Με τη χρήση της Κάλεσε ή Call μπορεί όμως να το κάνει, και αυτό γιατί αλλάζουν μερικά πράγματα εσωτερικά και έτσι μπορεί να εκτελεί πολλές φορές. Σε αυτόν τον δεύτερο τρόπο δεν ισχύει η δυνατότητα αλλαγής τμημάτων.

Η αλλαγή τμημάτων πριν την χρήση λέγεται "decoration" αλλά εδώ ελληνικά θα το λέγαμε διαμόρφωση! Προϋπόθεση είναι να γνωρίζουμε τα ονόματα των τμημάτων ενός τμήματος. Αλλά εδώ δεν υπάρχει θέμα, ο κώδικας των τμημάτων είναι ανοικτός! Από το να γράψουμε νέο κώδικα ή να βάλουμε στον υπάρχον κώδικα λογική για το τι θα χρησιμοποιεί και να έχουμε ένα "σεντόνι" κώδικα, μπορούμε να δώσουμε την διαμόρωσή του κατά την κλήση.

Το παρακάτω είναι ένα παράδειγμα με εντολές στα αγγλικά. Το ενδιαφέρον εδώ είναι ότι αλλάζουμε κατά την κλήση και το τμήμα ενός αντικειμένου (Ομάδα ή Group). Αυτό γίνεται γιατί το αντικείμενο αυτό είναι στατικό, δηλαδή δημιουργείται κατά την εκτέλεση στο τμήματος, και παραμένει ως έχει μέχρι το τμήμα να τερματίσει (στατικό δεν σημαίνει ότι δεν αλλάζει τιμές, αλλά ότι έχει συγκεκριμένο χώρο και δεν μπορεί να μετακινηθεί, δεν αποτελεί αντικείμενο με δείκτη - μπορεί όμως να αντιγραφεί σε άλλο που μετακινείται εντός πινάκων ή καταστάσεων ή σωρών, δηλαδή αντικειμένων που δέχονται αντικείμενα με δείκτη).

Για να γίνει πιο δύσκολο κάπως, το τμήμα recuirsive του m καλεί τον εαυτό του. Όμως εμείς θέλουμε να τρέξουμε το k χωρίς να συμβεί αυτό σίγουρα! Φτιάχνουμε το stop_recuirsive στο τμήμα έξω από το k και το περνάμε ως m.recuirsive. Τώρα τρέχει χωρίς να εκτελεί το κώδικα που είχε από "προγραμματισμό", αλλά με το κώδικα από "διαμόρφωση", ή decoration (η αντιστοιχία της αγγλικής δεν έχει σχέση με την διακόσμηση στο τρέχον κείμενο, αλλά με την διαμόρφωση).

Η διαμόρφωση ξεκινάει με ονόματα που δίνουμε. Θα μπορούσαμε να δίναμε ένα όνομα που δεν υπάρχει, αλλά θα έπρεπε να είχαμε "λογική" εντός του τμήματος για να κάνει κάτι γι΄αυτό, πράγμα όμως που μας βγάζει εκτός σκοπού. Μπορούμε να δώσουμε ένα  υπάρχον όνομα και στο τμήμα που καλούμε και στο τμήμα που καλεί, ή να δώσουμε ένα διαφορετικό από το τμήμα που καλεί και εκεί λέμε ΩΣ ή AS στα αγγλικά.
Στο παράδειγμα δίνουμε τρία τμήματα, το ένα είναι τμήμα αντικειμένου, και τα άλλα δυο είναι απλά τμήματα, το ένα όμως θα πάει και αυτό σαν τμήμα αντικειμένου.
Παρόλο που δώσαμε τμήμα αντικειμένου σε τμήμα αντικειμένου δεν έχουμε κάποια "Σύνδεση" με το τμήμα του τμήματους που καλεί γιατί συνδέεται αυτόματα με τμήμα αντικείμενου στο προορισμό.



form 60,32
module k {
      group m {
            z=500
            module recuirsive (x) {
                  Print x, .z
                  Modules ?
                  List
                  \\ just a waiting for keypress
                  Push Key$ : Drop
                  .z/=2
                  if x>0 then call .recuirsive x-1
            }
            module alfa {
                  print number
            }
            module alfa {
                  print number**2
            }
      }
      Modules ?
      m.recuirsive 10
      m.alfa number
      module kkk {
            print number/2
      }
      kkk 20
      Modules ?
}
group mine {
      z=1000
      module klm {
            drop
            print "error", .z
      }
}
module kkk {
      print number*20
}
module stop_recuirsive {
      drop
}
mine.klm 100
\\ decorated call for k
k 100 ; m.alfa as mine.klm, m.recuirsive as stop_recuirsive, kkk
\\ call can't be decorated
Report "Just Call K 100"
call k 100


Στο παρακάτω παράδειγμα βλέπουμε ότι αν περάσουμε τμήμα αντικειμένου σε τμήμα τότε το τμήμα αυτόματα "γνωρίζει" που ανήκει, δεν χάνεται η πληροφορία όπως θα χανόταν αν ο προορισμός ήταν τμήμα αντικειμένου.

Παρατηρούμε ότι η τιμή του a.x αλλάζει μετά την κλήση και αυτό φαίνεται ως πέρασμα με τιμή! Όμως στον αρχικό κώδικα του τμήματος alpha αυτό δεν είχε καν λογαριαστεί! Αυτή είναι η έννοια της διαμόρφωσης ή decoration, να προσδίδουμε λειτουργικότητα έξω από το σχεδιασμό του τμήματος.

Σκοπίμως έχει μπει η test "me"  (το τι θα γράψουμε στο αλφαριθμητικό δεν έχει σημασία, πέρα από το ότι θα φανεί στη φόρμα ελέγχου). Με το που θα εκτελεστεί η εντολή θα ανοίξει η φόρμα ελέγχου και μπορούμε να πατάμε το "Επόμενo Βήμα" και αν εκτελούμε μια προς μια τις εντολές και να βλέπουμε χρωματισμένο τον κώδικα και σημειωμένη την εντολή που εκτελούμε!



\\ Revision 5 Version 8.8
\\ Decorated modules
test "me"
Group a {
      x=100
      module finish (a) {
            .x+=a
            print "My good finish", .x
      }
}
module beta {
      print "beta"
}
module alpha (b){
      module finish (x){
            print "standard finish", x
      }
      module delta {
            print "internal delta"
      }
      print "ok", b
      delta
      finish 50
}
print a.x
alpha 100 ; delta as beta, finish as a.finish
print a.x
alpha 200
Modules ?




Αναθεώρηση 4 (Έκδοση 8.8) και οδηγίες για τον διορθωτή

Ίσως η τελευταία αναθεώρηση για αυτή τη σεζόν (από Νοέμβριο πάλι), λόγω άλλων εργασιών. Πιθανά bugs θα δώσουν νέα αναθεώρηση αλλά δεν θα γίνει κάποια επέκταση στο κώδικα.

Έγινε έλεγχος για όλα τα προγράμματα - δοκιμών- και η συγκεκριμένη αναθεώρηση θεωρείται η πιο καλή και από άποψη ταχύτητας.

Στον διορθωτή μπήκαν μερικοί αυτοιματισμοί:
  • Με ctrl+enter μπαίνουν αυτόματα τα άγκυστρα { } και ο δρομέας πάει στην γραμμή ανάμεσα με υπολογισμένη την αριστερή εσοχή.
  • Όταν πατάμε το πλήκτρο  παρένθεση "(" μπαίνει αυτόματα η συνέχεια ")" και ο δρομέας βρίσκεται ανάμεσα.
  • Όταν πατάμε το διπλό εισαγωγικό " μπαίνει αυτόματα η συνέχεια " και ο δρομέα βρίσκεταΙ ανάμεσα.
Για υπενθύμιση μόνο (υπήρχαν πριν):

Τα ctrl F2/ctrl F3 (και shift F2/ shift F3) ανοίγουν το διάλογο για την αναζήτηση πάνω και κάτω.

Συνεχόμενα F2/F3 πάμε στο επόμενο κατά τη διεύθυνση. Αν μαρκάρουμε μια λέξη με απλό κλικ και πατήσουμε ένα από τα F2/F3 τότε αυτή τη λέξη αναζητούμε.

Μπορούμε να αλλάξουμε κεφαλαία σε πεζά σε κάποια γράμματα σε  μια λέξη (εδώ οι τόνοι έχουν σημασία), και με το F4 θα γίνουν οι αλλαγές σε όλο το τμήμα/συνάρτηση (στο τμήμα που βλέπουμε το όνομα πάνω αριστερά).

Αλλαγές πολλαπλές (με πολλαπλό undo) κάνουμε με το F5 αφού έχουμε επιλέξει με απλό κλικ (αριστερό) μια λέξη.

Το ctrl+Z είναι το Undo, το ctrl+Y το Redo.

Το Tab μετατρέπεται αυτόματα σε διαστήματα (6 διαστήματα)
Με Tab σε πολλαπλές γραμμές μετακινούμε όλες τις γραμμές δεξιά βάζοντας περισσότερη εσοχή
Με ctrl+Tab βγάζουμε εσοχές (δουλεύει και για πολλαπλές γραμμές). Αν πατάμε συνέχεια τον συνδυασμό αυτό σε μια ομάδα γραμμών στο τέλος θα βγούν όλες οι εσοχές, ακόμα και αν είναι μικρότερες από 6 διαστήματα

Στην αντιγραφή στο πρόχειρο γίνεται εξαγωγή σe HTML και οι εσοχές μετατρέπονται σε non breaking space

Μπορούμε να βγούμε από το διορθωτή ακυρώνοντας όποιες αλλαγές έχουμε κάνει με shift-F12

Ο διορθωτής δεν έχει πρακτικό όριο χαρακτήρων στην γραμμή. Δεν υπάρχει οριζόντια μπάρα ολίσθησης (υπάρχει κρυφή κάθετη, που φαίνεται όταν είναι από πάνω το ποντίκι). Η μετακίνηση οριζόντια γίνεται αυτόματα. Μπορούμε με τα Home και End να μετακινηθούμε άμεσα στην αρχή ή το τέλος. Το Home εναλλάσεται, μια φορά στην αρχή της γραμμής και μια φορά στην αρχή χαρακτήρων πάνω στην γραμμή (μετά τα αρχικά διαστήματα δηλαδή)

Όταν γράφουμε στον διορθωτή αυτόματα μεταφέρει την γραμμή που γράφουμε στο κέντρο. Μπορούμε να ολισθήσουμε πάνω κάτω το κείμενο χωρίς μετακίνηση του δρομέα, οπότε με ένα πάτημα πλήκτρου (και με βελάκια γίνεται) επανέρχεται η γραμμή διόρθωσης στο κέντρο. Η ολίσθηση αυτή γίνεται ή με την μπάρα ολίσθησης ή με κράτημα πατημένου του αριστερού πλήκτρου του ποντικιού και μετακίνηση (αντίστροφη από την μπάρα ολίσθησης, σαν να σπρώχνουμε το κείμενο, δηλαδή να πατήσουμε και σπρωξουμε προς τα πάνω θα δούμε τις γραμμές να ανεβαίνουν).

Τα πλήκτα PageUp/PageDown και το ροδελάκι του ποντικιού (και αυτό κάνει PageUp/PageDown) αλλάζουν ανά μισή σελίδα (πάντα δείχνει ο διορθωτής μια γραμμή από τη μισή σελίδα που φεύγει) και μετακινούν τον δρομέα.

Τα ctrl-x, ctrl-c, ctrl-v λειτουργούν κανονικά. Το ins δεν χρησιμοποιείται εδώ.

Τα PageUp/PageDown/Home/End χρησιμοποιούνται με το Shift για να μαρκάρουμε κώδικα
Όπως και τα βελάκια με Shift μαρκάρουν κώδικα. Ο μαρκαρισμένος κώδικας είναι λευκός με διαφορετικό φόντο.

Ο χρωματισμός κώδικα γίνεται στον διορθωτή, άμεσα. Η Μ2000 δεν αποθηκεύει τη χρωματική πληροφορία στα τμήματα και τις συναρτήσεις, επειδή ο χρωματιστής είναι πολύ γρήγορος! Χρωματίζει ότι πρέπει να δείξει, και κρατάει τοπικά την πληροφορία. Ορισμένες φορές μπορεί να εκτιμήσει τον χρωματισμός διαβάζοντας προηγούμενες γραμμές! Δουλεύει με αναδρομή, οπότε χρωματίζει κατάλληλα και τις εκφράσεις.

Χρήσιμα πλήκτρα στην διόρθωση:

  • Ctrl+F1 (υπάρχει και στο αναδυόμενο μενού - σε Linux το Ctrl+F1 δεν δουλεύει), ανοίγει τη βοήθεια για την επιλεγμένη λέξη. Η βοήθεια εκτός από αυτό που δείχνει, μπορεί να χρησιμοποιηθεί για να γράψουμε (μέσα στο κείμενο που εμφανίζει) μια λέξη και με κλικ πάνω σε αυτήν κάνει αυτόματα αναζήτηση. Επίσης μπορούμε να αντιγράφουμε κώδικα από τη βοήθεια στο διορθωτή. 
  • F1 αλλαγή από αναδίπλωση σε μη αναδίπλωση παραγράφου (γίνεται πολύ γρήγορα και δεν χάνεται η θέση του δρομέα)
  • F12 ανοίγει την βοήθεια η οποία τώρα δείχνει μια λίστα τμημάτων (όσα είναι γενικά, ή ήδη φορτωμένα) και με κλικ σε αυτά βλέπουμε το κώδικα (όχι χρωματισμένο). Η βοήθεια έχει στην άκρη δεξιά κρυμμένη την μπάρα ολίσθησης, αλλά δουλεύει και με ολίσθηση με  κράτημα του πλήκτου πατημένο και τράβηγμα!
  • F6, F7, F8 είναι οι σελιδοδείκτες και ορίζονται/επιλέγονται/διαγράφονται με ένα πλήκτρο. Όταν πατήσουμε το F6 μια φορά και αυτό δεν έχει κάτι στην "μνήμη" τότε ορίζει τη θέση του δρομέα (βάσει παραγράφου, δηλαδή αν βάλουμε άλλες πριν δεν χάνει την συγκεκριμένη παράγραφο). 'Οταν πατήσουμε πάλι το F6 από θέση εκτός της θέσης της μνήμης μας πάει εκεί που δείχνει. Αν πατήσουμε πάλι το F6 στη θέση της μνήμης που έχει τότε την καταργεί. Σε κάθε περίπτωση βγαίνουν μηνύματα για το τι κάνουμε και επίσης όταν ο δρομέας είναι στη θέση κάποιου σελιδοδείκτη τότε αυτό φαίνεται στην επικεφαλίδα του διορθωτή.
  • F9 μέτρηση λέξεων (δεν μετράει αριθμούς και σύμβολα)
  • F10 Εμφάνιση μη εκτυπώσιμων χαρακτήρων (κενών/σύμβολο παραγράφου). Βοηθάει να δούμε αν έχουμε αφήσει κενά στη γραμμή -(ο διορθωτής δεν πειράζει τα κενά)
  • F11 αποχρωματισμός+ αλλαγή εμφάνισης επικεφαλίδας (4 καταστάσεις οι οποίες έρχονται η μία μετά την άλλη σε κάθε πίεση του F11)
  • Esc βγαίνουμε από το διορθωτή κανονικά!
Με την εντολή Φόρμα ορίζουμε το μέγεθος των χαρακτήρων της οθόνης βάσει διαστάσεων:
Πχ. η παρακάτω εντολή θα φτιάξει μέγεθος χαρακτήρων για 40 χαρακτήρες (μη αναλογικής γραφής) με 25 γραμμές και αυτόματα θα έχει φτιάξει το διάστιχο ώστε να καλύψει όλο το παράθυρο της κονσόλας.(το παράθυρο μπορεί να μετακινηθεί και να αλλάξει θέση, αλλά δεν θα το δούμε εδώ αυτό).


Φόρμα 40, 25
Form 40, 25
για τμήμα:
Σ αλφα
edit a
για συνάρηση:
Σ αλφα()
edit a()

σκέτο το Σ ή το Edit ανοίγει το διορθωτή με τις καταγραφές των άμεσων εντολών και μπορούμε εκεί να τις διορθώσουμε ή να προσθέσουμε. Όταν θα βγούμε με Esc τότε με τα βελάκια άνω και κάτω επιλέγουμε μια εντολή (μια παράγραφο που μπορεί να έχει εντολές η μία μετά την άλλη με διαχωρισμό με άνω και κάτω τελεία)

Τρίτη 23 Μαΐου 2017

Αναθεώρηση 3 (Έκδοση 8.8)

Σε αυτήν την αναθεώρηση εκτός από μικρές διορθώσεις, μπήκαν πρόσθετα πράγματα ειδικά στο τρόπο χειρισμού αντικειμένων που φορτώνουμε από τα Windows.

Το απλό πρόγραμμα που δείχνει μια φόρμα του vbRichClient, με κίτρινο φόντο, και ώρα στο τίτλο της φόρμας.

' cConstructor
\\ Title "Any Title Here",0  \\ hide console
Declare appform application form
Declare New_c "{CAECC935-9C70-4176-8BED-C39B2E33B31F}"
Method New_c, "Cairo" as Cairo
Print Type$(New_c)
Print Type$(Cairo)
With Cairo, "WidgetForms" as Cairo.WidgetForms
Method Cairo.WidgetForms, "Create", 1,"My Main-Form Caption, Click Me!" withevents as Form1
Print type$(Form1)
'  Form.WidgetRoot.BackColor = vbYellow
vbYellow=65535
vbRed=255
vbFixedDialog=3
vbSizableToolWindow=5
' Make a variable to hold a link, but no reference to value - only a hard link to Form1 and the property "WidgetRoot"
Print Type$(Form1)
With Form1,  "visible" as visible
With Form1, "hWnd" as Form1.hWnd
With Form1, "caption" as caption$
Function Form1_KeyPress {
\\stack
      Read &KeyInteger
      If KeyInteger=13 then {
            Print
      } Else {
            Print chrcode$(KeyInteger);
      }
      Refresh
}
Function Form1_Click {
\\\stack
            If pos>0 then Print
            Print "Hello There", now
            caption$="ok.................."
            Refresh
}
for this {
With Form1,"WidgetRoot" set WidgetRoot
With WidgetRoot, "BackColor", vbYellow
}
Method Form1 "Show", 0, appform
Refresh
Every 100 {
      if Form1.hWnd else exit
      caption$=str$(now,"hh:mm:ss")
      \\  if keypress(1) then exit  \\ click in console
}
Declare form1 nothing

Declare cairo nothing
Declare New_c nothing
Show


Και εδώ το πιο μεγάλο με νήμα που τρέχει πίσω από τις φόρμες! Δεν είναι τέλειο γιατί βγαίνει μια φορά το modal παράθυρο...(μετά δεν ξέρω γιατί δεν ξαναβγαίνει). \

Οι συναρτήσεις για τα γεγονότα εκτελούνται με τρόπο ώστε οι μεταβλητές του τμήματος να είναι θεατές σε αυτές. (ενώ οι κανονικές συναρτήσεις δεν έχουν αυτήν την ιδιότητα). Ότι μεταβλητές φτιάξουμε θα διαγραφούν. Μεταβλητές που διαβάζονται με αναφορά επειδή μπορούν να πάρουν μία μόνο αναφορά για κάθε περίπτωση πρέπει να τις διαβάσουμε ως νέες (Read New), που σημαίνει ότι πρόσκαιρα θα μπορούν να συνυπάρχουν δυο ίδιες μεταβλητές στο όνομα αλλά όχι στη τιμή. Απλά η πιο πρόσφατη θα διαγραφεί πρώτη.
Τα γεγονότα από τις φόρμες έρχονται ένα κάθε φορά (στην αρχή ερχόντουσαν όλα μαζί και ναι μεν εκτελούνταν, αλλά υπήρχε θέμα και μάλιστα υπήρχαν προβλήματα με "διαρροή μνήμης" (memory leaks). Τώρα έχει διορθωθεί η κατάσταση. Στις φόρμες της Μ2000 δεν υπάρχει αυτό το πρόβλημα γιατι διαχειρίζεται το σύστημα εσωτερικά την ροή των γεγονότων. Τώρα σε αυτήν την αναθεώρηση έχουμε επίσης χειρισμό των εξωτερικών γεγονότων από το περιβάλλον της Μ2000. Λέμε ότι είναι εξωτερικά γιατί τρέχουν στο dll της vbRitchClient5. Στην αναθεώρηση αυτήν έχω βάλει ένα φίλτρο όπου μηνύματα που δεν τα χρησιμοποιούμε να βγαίνουν εκτός (έρχονται αλλά δεν προωθούνται). Αυτό το φίλτρο καθαρίζει με την δημιουργία του Event Sink Object και σχηματίζεται αν η φόρμα είναι ορατή (οπότε αν δεν είναι δεν βάζει φραγή, πράγμα που θα έκανε αν οι συναρτήσεις για τα γεγονότα ορίζονταν μετά την γραμμή που ορίζουμε το αντικείμενο Event Sink).





Έγινε διόρθωση για τις νεότερες εκδόσεις της Μ2000, όπου οι μεταβλητές (παράμετροι) στις συναρτήσεις εξυπηρέτησης γεγονότων δεν είναι με αναφορά, πρέπει να τις διαβάζουμε χωρίς το σύμβολο της αναφοράς &. Παλαιότερα όλες έρχονταν σαν να ήταν με αναφορά.


' cConstructor
'Title "",0
Declare AppForm Application Form
Declare New_c "{CAECC935-9C70-4176-8BED-C39B2E33B31F}"
Method New_c, "Cairo" as Cairo
Print Type$(New_c)
Print Type$(Cairo)
With Cairo, "WidgetForms" as Cairo.WidgetForms
Method Cairo.WidgetForms, "Create", 1,"My Main-Form Caption, Click Me!" as Form1
Print type$(Form1)
'  Form.WidgetRoot.BackColor = vbYellow
vbYellow=65535
vbRed=255
vbFixedDialog=3
vbSizableToolWindow=5
' Make a variable to hold a link, but no reference to value - only a hard link to Form1 and the property "WidgetRoot"
Print Type$(Form1)
With Form1, "WidgetRoot" as Form1.WidgetRoot, "visible" as visible
Print type$(Form1.WidgetRoot)
With Form1, "hWnd" as Form1.hWnd
With Form1.WidgetRoot, "BackColor", vbYellow
Method Cairo.WidgetForms, "Create", vbFixedDialog,"MyDialog ... Click Me!",-1 , 800, 600 as Form2

With Form2, "WidgetRoot" as Form2.WidgetRoot
With Form2.WidgetRoot, "BackColor", vbRed
         
Method Cairo.WidgetForms, "Create", vbSizableToolWindow, "MyToolWindow - Resize Me!", -1, 800, 600 as Form3
Method Form3,"SetMinMaxDimensions", 200, 400, 300, 600
With Form3, "visible" as Form3.visible
mClicks=0
one=false
Function Form2_Click {
        mClicks++
        With Form2, "Caption", "Click-Count so far:" +Str$(mClicks)
}
once=false
Function Form1_Move {
      Read New X, Y
      Print X, Y
      wait 1
}
Function Form2_Move {
      Read New X, Y
      Print X, Y
      wait 1
}
Function Form1_Click {
      Print envelope$() \\ return S is a string
      stack   \\ show empty string
      refresh
      if once then exit
      once=true
      Layer {
            Try ok {
            Report "First we show a modal Dialog-Window, and count the Clicks on it"
            if one else Method Form2 "Show", 1
            Report format$("The Dialog was clicked {0} times.", mClicks)
            Report  {Now we show a non-modal ToolWindow, which remains in the ForeGround of this Form
                              and will close itself automatically, when the MainForm is destroyed
                              }
            refresh
            if one then {
                  Form3.visible=true
                  Print Form3.visible
            } else Method Form3, "Show",0,Form1 : one=true
            }
            if error then print error$
            once = false
            Print "once=false"
      }
    
    
}
Thread {
try {
      If pos>0 then print
      Print now, visible, once
      }
      refresh
} as alfa interval 100
Print Visible
Declare WithEvents Form1
Declare WithEvents Form2
'Declare WithEvents Form3
Method Form1, "Show", 0, AppForm
Print Visible
\\Method Cairo.WidgetForms, "EnterMessageLoop"
Task.Main 100 {
      if Form1.hWnd else exit
'      if keypress(1) then exitEDIT
}
Threads erase
Declare form1 nothing
Declare form3 nothing
Declare cairo nothing
declare New_c nothing
Show

Δευτέρα 22 Μαΐου 2017

Νέα έκδοση 8.8 (rev. 2)

Σε αυτήν την έκδοση έκανα μερικές βελτιώσεις, μια εκ των οποίων είναι βασική γιατί αλλάζει ο τρόπος που εκτελούνται πράξεις:

Οι mod και div (και οι νέες mod# και div# ως ευκλείδειο υπόλοιπο και διαίρεση), (ελληνικά υπόλοιπο, υπολ και υπόλοιπο#, υπόλ# καθώς και δια και δια#), τώρα στο δεξιό σκέλος μπορούν να έχουν γινόμενα ή και διαιρέσεις

Το 10 div 2*2 ήταν (10 div 2)*2 και τώρα είναι 10 div (2*2). Επίσης το υπόλοιπο δουλεύει και για δεκαδικά, δηλαδή το 10.4 υπόλοιπο 4 θα δώσει 2.4

Μπορούμε να γυρίσουμε στο παλιό τρόπο με το switches "+DIV" ή Διακόπτες "+DIV". Αυτό μπορεί να γίνει πρόσκαιρα μέσα αν δοθεί μέσα σε τμήμα με set switches "+DIV"


Τετάρτη 17 Μαΐου 2017

Αναθεώρηση 25 (Έκδοση 8.7)

Σε αυτήν την αναθεώρηση βελτίωσα τις φόρμες σε ότι αφορά τις γραμματοσειρές, ώστε σε οθόνες με διαφορετικά dpi (από τα 96) να προσαρμόζονται αυτόματα τα αρχικά μεγέθη.

Στην εικόνα, σε Windows 8, έχει οριστεί μεγέθυνση 125%. Το πορτοκαλί παράθυρο είναι φόρμα της Μ2000, με δυνατότητα να χρωματίζει κώδικα της Visual Basic 6. Στο αριστερά κάτω παράθυρο φαίνεται μέρος του κώδικα (έχει δημοσιευθεί, αλλά τον βάζω ξανά παρακάτω)



Έχω προσαρμόσει την φόρτωση κειμένου σε μετατροπή από ελληνικό ANSI (με το 1049 μπορεί να διαβάζει ρωσικό ANSI (8bit). H LoadDoc μπορεί να διαβάσει και UTF-8, UTF-16LE, UTF-16BE.
Ονομάζουμε μια ιδιότητα MenuGroup με το "this" ώστε όλα τα στοιχεία του μενού να συνδέονται μεταξύ τους (είναι combobox που λειτουργούν ως μενού).

\\ notepad
Clear \\ Clear all variables/objects
Flush \\ Empty the stack
Title$="M2000 Pad"
typ$="txt"
Dir User
Greek
Declare NotePad Form
Declare Pad EditBox Form NotePad
Declare Inform1 Button Form NotePad
Method Inform1, "Colors", 15, #FFA000
With Inform1, "Locked", true
Declare File1 Combobox Form NotePad
Declare Edit1 Combobox Form NotePad
Declare Help1 Combobox Form NotePad
With File1,"label","File", "listtext" As list$, "list" As list$() '
With Edit1,"label","Edit",  "Mark", Color(255,100,0)
With Help1,"label","Help",  "Mark", Color(255,100,0)
With NotePad, "Title" As Caption$, "Visible" As Visible, "TitleHeight" As tHeight, "Sizable", True
With Pad, "Text" As Pad.Text$, "ShowAlways", True,"NoColor", True,"SelLength" as SelLength
Def TitleStr$(a$)=ucase$(left$(a$,1))+mid$(a$,2)
Filename$=Dir$+"Untitled.txt"
Caption$=TitleStr$(File.Name$(Filename$)) +" - M2000 Pad"
title caption$
Method NotePad,"move", 2000, 4000, 8000, 4000
Layer NotePad {Cls #FFA000}
With File1,"MenuStyle", True, "MenuWidth", 3000
With Edit1,"MenuStyle", True, "MenuWidth", 3000,"menuEnabled" as Enabled()
With Help1,"MenuStyle", True, "MenuWidth", 3000
With File1, "MenuEnabled" As mEnable()
For This {
      mi$="MenuItem"  \\ is a temporary variable only for For This Block
      With File1, "MenuGroup","This"
      Method File1, mi$,"Open",True
      Method File1, mi$,"Save",True
      Method File1, mi$,""    \\  only  a line here
      Method File1,"MenuRadio", "txt files", True, True
      Method File1,"MenuRadio", "bas files", True ,False
    
      Method File1, mi$,""
      Method File1, mi$,"Close",True
      Method File1, mi$,""
      Method File1, mi$,"Quit",True
    
      With Edit1, "MenuGroup","This"
      Method Edit1, mi$,"Cut",False
      Method Edit1, mi$,"Copy",False
      Method Edit1, mi$,"Paste",True
      Method Edit1, mi$,""
      Method Edit1, mi$,"Less Indent",True
      Method Edit1, mi$,"More Indent",True
      With Help1, "MenuGroup","This"
}


Document BackUp$="Write something..."
Pad.Text$=BackUp$
Function NotePad.Unload {
      Read New &Ok
      After 30 {call local File1.DblClick(8) }
      Ok=True


}
Function Notepad.Resize {
      Layer NotePad { Cls Color(255, 160, 0) ,0}
      With NotePad, "Width" As NP.Width, "Height" As NP.Height, "TitleHeight" As tHeight
      tHeight1=theight*2
      Method File1,"move", twipsX*2, tHeight, twipsX*80, tHeight
      Method Edit1,"move", twipsX*2+twipsX*80, tHeight, twipsX*80, tHeight
      Method Help1,"move", twipsX*2+twipsX*160, tHeight, twipsX*80, tHeight
      Method Inform1,"move", twipsX*2+twipsX*240, tHeight, twipsX*160, tHeight
      If NP.height>1000 Then {
            Method Pad,"move", twipsX*2, tHeight1, NP.Width-twipsX*5, NP.Height-tHeight1-twipsx*3
            With Pad, "NoWrap" As NoWrap
            If Not NoWrap Then Method Pad,"Resize"
      }
}
Function Edit1.OpenMenu {
            Local X
            X=SelLength>0
            Enabled(0)=X
            Enabled(1)=X
}


Function Edit1.DblClick {
      Read Local Edit1index
      Select Case Edit1index
      Case 0
            {
            Method Pad,"mn1sub"
            Method Pad,"Resize"
            }
      Case 1
            Method Pad,"mn2sub"
      Case 2
            {
                 Method Pad, "mn3sub"
                 Method Pad,"GetFocus"
                 Method Pad,"Resize"
           }
        Case 4
           {
                  Method Pad,"PressKey", 9, 1
            }
        Case 5
           {
                  Method Pad,"PressKey", 9, 0
            }
      End Select


}
Function Pad.Inform {
      Read New L, P
      With Inform1, "Caption", format$("{0}-{1}", L,P)
      Method Pad,"Show"
}
Function Pad.PopUp {
      Read Local X, Y
      Method Pad,"PopUpMenu", "",X , Y
}
Function File1.MenuChecked {
Read New RadioIndex \\ 3 or 4
If RadioIndex =3 then {
      After 30 { local a$="."+file.type$(Filename$), b$=File.name$(Filename$)
      Filename$=File.path$(Filename$)+Left$(B$,Len(B$)-Len(a$))+".txt"
      Caption$=TitleStr$(File.Name$(Filename$)) +" - M2000 Pad"
      typ$="txt"
      With Pad, "ColorCollection1", "","NoColor", True
      Method Pad, "Show"
      }
} else.if RadioIndex =4 then {
     After 30 { local a$="."+file.type$(Filename$), b$=File.name$(Filename$)
      Filename$=File.path$(Filename$)+Left$(B$,Len(B$)-Len(a$))+".bas"
      Caption$=TitleStr$(File.Name$(Filename$)) +" - M2000 Pad"
      typ$="bas"
      With Pad, "ColorCollection1", "|AND|OR|XOR|NOT|CLS|DEBUG.|PRINT|DECLARE|CONST|GOTO|DO|LOOP|WHILE|WEND|WITH|REFRESH|LET|GET|SET|DOEVENTS|SELECT|CASE|FALSE|TRUE|OPTION|EXPLICIT|LIB|DIM|REDIM|PUBLIC|PRIVATE|FUNCTION|SUB|IF|THEN|ELSE|ELSEIF|END|SELECT|FOR|NEXT|TO|AS|LONG|BOOLEAN|STRING|OBJECT|EXIT|BYVAL|NEW|LEFT$(|LEFT(|RIGHT$(|RIGHT(|MID$(|MID(|UBOUND(|LBOUND(|CSTR(|CDBL(|CLNG(|STR$(|STRING$(|INSTR(|ASC(|CHR(|CHR$(|COS(|SIN(|LOG(|RGB(|REPLACE(|","NoColor", False
      Method Pad, "ReColor"
      Method Pad, "Show"
      }
}


}
Function File1.DblClick {
\\ we use functions As subs here
\\ each function and each module have a name (define a namespace)
\\ but here real module name is the File1.DblClick() host module
\\ this is done because is a Gui Event Service Function
\\ and is call with Local tag (Call Local)
      Read New File1index
      Local cont, cont2, f$, NL$={
      }
      File1index++
      \\ Because we want some jumps..we use  On Goto
      \\ on Goto need here a block
      {
      On File1index Goto Open1, Save1, ExitNow, ExitNow, ExitNow, ExitNow, Save2, ExitNow, Unload
Exitnow:
      Exit
Open1:
      If Pad.Text$<>BackUp$ Then {
            If Ask("Save Changes first?",Title$, "Yes","No")=1 Then Goto Save1
      }
     Layer NotePad {
           Open.file filename$,,"Load Text ("+typ$+") File",typ$
     }
     Method Pad,"GetFocus"
     Read f$
     If f$<>"" Then {
           Filename$=f$
           If exist(F$) then {


           Clear BackUp$
         
           Load.Doc BackUp$, f$, 1032 \\ Greek - 1049 for Russian
         
           Caption$=TitleStr$(File.Name$(Filename$)) +" - M2000 Pad"
           title caption$
           Pad.Text$=BackUp$
           } else Pad.text$="": Clear BackUp$
           Method Pad, "ReColor"
      }
      Exit
Save1:
      Layer NotePad {
            Save.As Filename$,,"Save Text ("+typ$+") File",typ$
      }
      if not cont2 then Method Pad,"GetFocus"
      Read f$
      If f$="" Then Exit
      If lcase$(file.type$(f$))<>typ$ then f$=f$+"."+typ$
      If Exist(f$) Then If Ask(NL$+"Overwrite"+NL$+f$,Title$, "Yes","No")<>1 Then Exit
      Try ok {
        Flush BackUp$
        BackUp$=Pad.Text$
        Save.Doc BackUp$, f$
        filename$=f$
        Caption$=TitleStr$(File.Name$(Filename$)) +" - M2000 Pad"
      }
     If ok else beep
     If not cont then Exit
Save2:
      cont=True
      If Pad.Text$<>BackUp$ Then {
            If Ask("Save Changes?",Title$, "Yes","No")=1 Then Goto Save1
      }
      Clear BackUp$
      Pad.Text$=""
      If Cont2 then {
            Method NotePad, "CloseNow"
      } Else {
            FileName$=Dir$+"Untitled."+typ$
            Caption$=TitleStr$(File.Name$(Filename$)) +" - M2000 Pad"
            Method Pad, "Resize"
      }
      Exit
Unload:
      Cont2=True : Goto Save2
      }
}
Function Help1.OpenMenu {
      Local A, info$
      Info$={
            This is an example
            of a notepad
            written for M2000 Environment
            use F1 to change wrap
            }
      A=Ask(info$,Title$,"","")
      Method Pad, "GetFocus"


}
Call Local Notepad.Resize()
\\ open As modal
Title Title$, 0
After 100 {Title Title$}
Method NotePad,"Show" , 1 \\ 1 for Modal
Declare Pad Nothing
Declare NotePad Nothing
Print "Done"