Τετάρτη 17 Νοεμβρίου 2021

Αναθεώρηση 38 Έκδοση 10 (Αναβάθμιση του GUI)

 Σε αυτήν την αναθεώρηση έγιναν αρκετές προσθήκες, κύρια στο σύστημα των παραθύρων (GUI) της Μ2000. 

Παλιότερα ήθελαν όλα τα στοιχεία διπλό κλικ για να πάρουν εντολή. Το απλό τα επιλέγουν. Επίσης έχουν και την ολίσθηση δεξιά για να πάρουν επίσης εντολή. Στην νέα αναβάθμιση ισχύει το διπλό κλικ αλλά την πρώτη φορά, όταν πάρει την εστίαση η φόρμα, μετά συνεχίζου με απλό κλικ, ενώ παράγονται τα γεγονότα του απλού και του διπλού κλικ.

Τα στοιχεία ΠΛΗΚΤΡΟ (Button) και ΕΠΙΛΟΓΗ (Checkbox) μπορούν να επιλεγούν και με βελάκια αυτόματα. Όλα βέβαια επιλέγονται με TAB και SHIFT TAB (αυτό υπήρχε). Νέο τώρα είναι να βάλουμε πλήκτρο που θέλουμε με συνδιασμό ALT CTRL SHIFT:

Στο πρόγραμμα έχω βάλει δυο κλήσεις σε μεθόδους "AccKey", από μια σε κάθε ΠΛΗΚΤΡΟ (button). Εδώ το Opcode είναι 1, που σημαίνει ότι θα πάρει εστίαση και θα πατήσουμε το πλήκτρο, όταν δώσουμε το + στο ένα και το CTRL+R στο άλλο.

Η εντολή Μέθοδος ή Method, είναι κάπως πολύπλοκη, γιατί σχετίζεται με κλήσεις σε αντικείμενα COM, εξωτερικά, και εδώ τα στοιχεία GUI της Μ2000 ενώ είναι εσωτερικά τα χειριζόμαστε με το σύστημα των εξωτερικών. Σε αυτή λοιπόν την εντολή μπορούμε να δώσουμε τιμές σε παραμέτρους με όνομα (εκτός σειράς δηλαδή). Δείτε ότι στην πρώτη λείπουν οι shift, ctrl και alt, ενώ στη δεύτερη λείπουν τα alt και shift. Κάποια στιγμή θα ετοιμάσω ένα εγχειρίδιο και για αυτή την εντολή σε σχέση με διάφορα αντικείμενα!

Τα αντικείμενα που φτιάχνουμε με DECLARE ή ΌΡΙΣΕ διαγράφονται στο τέλος εκτέλεσης του τμήματος. Δεν μπορούμε να τα επιστρέψουμε, ένα επίπεδο παραπάνω. Όλη η δουλειά πρέπει να γίνει σε αυτό το τμήμα που τα φτιάξαμε ή σε τμήματα που καλούμε είτε τα ορίσουμε γενικά (DECLARE GLOBAL) είτε τα περάσουμε με αναφορά (και με τιμή πάλι δεν αλλάζει, γιατί περνάμε δείκτη στο αντικείμενο). Ουσιαστικά ο δείκτης είναι μοναδικός, υπάρχει μόνο σε μια θέση και ότι και να κάνουμε θα πάρουμε έμμεσο δείκτη. Με αυτό το τρόπο είναι βέβαιο ότι θα διαγραφεί το αντικείμενο με το τερματισμό του τμήματος, είτε γίνει κανονικά είτε επειδή βγήκε κάπου λάθος που κάναμε στο κώδικα, είτε γιατί σταματήσαμε (όσο τρέχει στη κονσόλα της Μ2000)  με το Esc, Ctrl+C, είτε ακόμα και με το Break (τα δυο τελευταία ρωτάνε αν θέλουμε όντως προχωρήσουμε σε τερματισμό εκτέλεσης το πρώτο και καθαρισμό περιβάλλοντος το δεύτερο).

Όταν οι φόρμες εκτελούνται με εκκίνηση απευθείας από το M2000.exe (χωρίς να ανοίξει η κονσόλα της Μ2000), τότε δεν υπάρχει άμεσος τρόπος τερματισμού εκτός από το Χ που εμφανίζεται στην γραμμή εργασιών (task bar) όταν πάμε το δείκτη του ποντικιού πάνω στο εικονίδιο του αντοικτού προγράμματος). Τα σήματα δηλαδή τα παίρνει η κονσόλα, όσο είναι ανοικτή (αν είναι ελαχιστοποιημένη μπορούμε να την ανοίξουμε). Μια εντολή όμως Τίτλος "", 0 την ελαχιστοποιεί και εξαφανίζει και το εικονίδιο από το Task Bar. (οι φόρμες έχουν δικό τους εικονίδιο στη Task Bar).

Ενώ τα τμήματα και οι συναρτήσεις είναι απομονωμένες από άλλο κώδικα, ειδικά οι συναρτήσεις για τα γεγονότα είναι σαν μέρη του τμήματος, και για το λόγο αυτό βλέπουν τα στοιχεία του τμήματος.Δείτε στη συνάρτηση TextBox1.ValidString, η οποία καλείται από το γεγονός ValidString του TextBox1. Επειδή φτιάχνουμε αναφορές με το &, στα ορίσματα που στέλνει το γεγονός (δηλαδή οι τιμές που θα αλλάξουμε θα επιστραφούν) θέλουμε σίγουρα να είναι νέες (δεν μπορεί ένα όνομα να πάρει δεύτερη αναφορά), έτσι το Διάβασε Νέα κάνει αυτή τη δουλειά. Επίσης καλούμε το Local1 με ειδική κλήση, την Call Local, η οποία καλεί το Local1 ως επίσης μέρος του τμήματος, δηλαδή με ίδια θέαση μεταβλητών. Σε αυτή περνάμε την τιμή (by value) της ιδιότητας VarText την οποία έχουμε συνδέσει με το όνομα textbox1.value$ (είναι αλφαριθμητικό, ή χαρακτήρες). Η εντολή With ή Με (υπάρχει και η Με εντός της Επίλεξε Με αλλά ξεχωρίζει για τον διερμηνευτή) είτε δίνει τιμές σε ιδιότητες, είτε συνδέει ιδιότητες με αναγνωριστικά (με ονόματα). Τα ονόματα στη Μ2000 μπορούν να έχουν και τελείες. Εδώ θα μπορούσαμε να βάλουμε οτιδήποτε άλλο αρκεί να είχαμε το $ στο τέλος. Η Μ2000 θέλει να ξεχωρίζει τι είναι αριθμός και τι αλφαριθμητικό. Θα μπορούσε να χρησιμοποιηθεί το στοιχείο Κείμενο που έχει ειδική διαμόρφωση για αριθμούς, και δεν χρειάζονταν το LOCAL1. Όμως το να βλέπει κανείς πως ο έλεγχος αλλαγών μπορεί να γίνει μέσα από το πρόγραμμα είναι κάτι θετικό.

Όταν πατάμε το δεύτερο πλήκτρο εμφανίζεται ένα MessageBox και αυτό φτιαγμένο στη Μ2000. Καλούμε με νήμα με τη εντολή Μετά ή After για να αλλάξουμε εστίαση.  Δείτε το πρόγραμμα Demo1 που περιστρέφει ένα 3D γραφικό στη φόρμα και ανοίγουμε το MessageBox το οποίο περιμένει να πατήσουμε το OK ή το Esc πλήκτρο και ταυτόχρονα νήματα εκτελούν την περιστροφή. Η Μ2000 έχει ένα εσωτερικό διαχειριστή νημάτων!


Module CheckIt {

      Declare form1 form
      Declare textbox1 textbox form form1
      Declare buttonInc Button form form1
      Declare buttonRND Button form form1
      Method textbox1, "move", 2000,2000,4000,600
      Method buttonInc, "move", 2000,3000,2000,600
      Method buttonRND, "move", 4000,3000,2000,600
      With form1, "Title", "Rosetta Code: GUI component interaction"
      With textbox1,"vartext" as textbox1.value$, "Prompt", "Value:", "ShowAlways", true
      With buttonInc,"Caption","Increment [+]"
      Method buttonInc, "AccKey", "+", opcode:=1

      With buttonRND,"Caption","Random [^R]"
      Method buttonRND, "AccKey", "R", ctrl:=true, opcode:=1
      textbox1.value$="0"
      Function Local1(new Feed$) {
            \\ this Function can be used from other Integer
            \\ this$ and thispos, exist just before the call of this Function
            local sgn$
            if feed$="" and this$="-" then thispos-- : exit
            if left$(this$,1)="-" then sgn$="-": this$=mid$(this$, 2)
            if this$<>Trim$(this$) then this$=Feed$ : thispos-- : exit
            If Trim$(this$)="" then this$="0" : thispos=2 : exit
            if instr(this$,"+")>0 and sgn$="-" then this$=filter$(this$, "+") : sgn$=""
            if instr(this$,"-")>0 and sgn$="" then this$=filter$(this$, "-") : sgn$="-"
            if filter$(this$,"0123456789")<>"" then this$=Feed$ : thispos-- : exit
            if len(this$)>1 then While left$(this$,1)="0" {this$=mid$(this$, 2)}
            this$=sgn$+this$
            if this$="-0" then this$="-" : thispos=2
        }
      Function TextBox1.ValidString {
                  \\ this Function called direct from textbox
                  Read New &this$, &thispos
                  Call Local local1(textbox1.value$)
      }
      Function buttonInc.Click {
               textbox1.value$=str$(val(textbox1.value$)+1, "")
      }
      Function buttonRND.Click {
            If AsK$("Change Value with random number", "Question", "Yes", "No")="Yes" Then {
                      textbox1.value$=str$(Random(0, 10000), "")
                      After 100 {Try {Method textbox1,"GetFocus"}}
            }
      }
      \\ open modal
      Method form1, "show", 1
      Declare form1 nothing
}
Checkit


Έγιναν αλλαγές και στα μενού. Τα μενού φτιάχνονται με στοιχεία ΛΙΣΤΑ.ΕΙΣΑΓΩΓΗΣ ή ComboBox. Το στοιχείο ΛΙΣΤΑ.ΕΙΣΑΓΩΓΗΣ συνδυάζει δυο στοιχεία, την ΕΙΣΑΓΩΓΗ ή TextBox, και μια ΛΙΣΤΑ ή ListBox, το οποίο εμφανίζεται πάνω από την φόρμα (μπορεί να βγει ένα μέρος του απέξω). Υπάρχει επιλογή να έχει ανοικτή ή κλειστή την ΕΙΣΑΓΩΓΗ, δηλαδή να λειτουργεί σαν ΠΛΗΚΤΡΟ, που όταν το επιλέγουμε με διπλό κλικ ανοίγει η ΛΙΣΤΑ για να επιλέξουμε. Επίσης η ΛΙΣΤΑ σε κάθε θέση της όταν είναι σε MenuStyle (έτσι λέγεται η ιδιότητα του ComboBox), μπορεί να έχει, είτε κάτι για επιλογή άμεσα, είτε κάτι που έχει μια βούλα δίπλα και αλλάζει σαν ON/OFF διακόπτης, είτε ανοίκει σε μια σειρά RADIO επιλογών, δηλαδή υπάρχει μια βούλα που μένει σε ένα από την σειρά επιλογών, ώστε να επιλέγουμε ένα από αυτά κάθε φορά, και τέλος μπορεί να υπάρχει διαχωριστικό. Επίσης κάποια στοιχεία στο μενού μπορεί να είναι απενεργοποιημένα. Στην εικόνα παρακάτω αυτά είναι με κόκκινα γράμματα. Στη νέα αναθεώρηση μπήκαν τα πλήκτρα άμεσης εκτέλεσης (με τα πλήκτρα γρήγορης εκτέλεσης δεν ανοίγουν καν τα μενού, και άμεσα δίνουν την εντολή που πρέπει) και αυτόματα εμφανίζεται ο συνδυασμός δεξιά με άλλο χρώμα. Δείτε την εικόνα παρακάτω (είναι από το meditor που υπάρχει στο Info, το οποίο υπάρχει στην εγκατάσταση της γλώσσας - έχει πάνω από 30000 γραμμές κώδικα,δείτε στην εικόνα δίπλα στο μενού τον αριθμό γραμμής).

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

Προς το παρόν δεν έχω βάλει εικονίδια. Ίσως γιατί τα αντιπαθώ! Γενικά θέλω να διαβάζει κανείς το μενού επιλογών. Τα γράμματα είναι μεγάλα σε σχέση με τα μενού των Windows. Όλα αλλάζουν εδώ, δηλαδή αν θέλουμε κάνουμε ακόμα μεγαλύτερα τα μενού! Στη φόρμα παρακάτω υπάρχει το γεγονός Resize που στοιχίζει τα στοιχεία. θα μπορούσε κάποιος να αλλάξει τα μεγέθη γραμματοσειράς και να τα στοιχίσει πάλι! 


Παρατηρήστε ότι τα μενού στις λίστες έχουν διάστημα αρκετό μεταξύ των επιλογών. Αυτό γίνεται με εντολή που ορίζει το κενό αυτό. Στο πρόγραμμα που έχει γραφτεί με τις αγγλικές εντολές της Μ2000 (υπάρχουν και σε Ελληνικά), έχει μπει μια Linespace 60  (δηλαδή 60 twips, όπου αν το pixel είναι 15twips μας δίνει 4 pixel διάστημα πάνω και κάτω από το στοιχείο - μιας γραμμής στο μενού). Αυτή την εντολή την δίνουμε πριν ορίσουμε τα στοιχεία για να την ακολουθούν όλα, ακόμα και το ΚΕΙΜΕΝΟ (EditBox) στο πρόγραμμα στην εικόνα!

Τα στοιχεία που βέπουμε (και εκείνα που δεν βλέπουμε) είναι τα παρακάτω. Το HelpPad ανοίγει κάτω από το Pad για να δείξει τη βοήθεια στη λέξη που επιλέξαμε (με F4 γίνεται αυτόματα η επιλογή λέξης όπου είναι ο δρομέας, δεύτερη φορά το F4 κάνει όλες τις ίδιες λέξεις με ίδια κεφαλαία και πεζά). Το άνοιγμα της βοήθειας γίνεται εδώ με το Ctrl+F στην επιλεγμένη λέξη (ή από το Help υπάρχει το InputBox που μας ζητάει ένα όνομα, ή τα αρχικά γράμματα). To inform ενώ είναι Button, το έχουμε κλειδωμένο και το χρησιμοποιούμε σαν Label δηλαδή να μας δείχνει αναφορά, κατά τη φόρτωση αρχείου (ασύγχρονη) και την γραμμή και τη στήλη του δρομέα στο Pad).

Declare NotePad Form
Declare Pad EditBox Form NotePad
Declare HelpPad EditBox Form NotePad
Declare File1 Combobox Form NotePad
Declare Edit1 Combobox Form NotePad
Declare Run1 Combobox Form NotePad
Declare Help1 Combobox Form NotePad
Declare Inform1 Button Form NotePad

Εδώ μας ενδιαφέρουν τα τέσσερα Combobox. Δίνουμε σε μια ιδιότητα Hover Αληθές, για να λειτουργεί η αυτόματη εστίαση (ημί εστίαση κατά μια έννοια). Δείτε ότι η With μπορεί σε μια γραμμή (όσο θέλουμε μήκος) να αλλάζει πολλες ιδιότητες. Εδώ δίνουμε και όνομα στην ιδιότητα label

With File1,"label","File", "Hover", true
With Edit1,"label","Edit", "Mark", Color(255,100,0), "Hover", true
With Run1,"label","Run", "Mark", Color(255,100,0), "Hover", true
With Help1,"label","Help", "Mark", Color(255,100,0), "Id" as Id$(), "Hover", true

Παρακάτω λέμε ότι θα είναι MenuStyle και ορίζουμε το πλάτος κάθε μενού σε twips.

With File1,"MenuStyle", True, "MenuWidth", 4000
With Edit1,"MenuStyle", True, "MenuWidth", 4800
With Run1,"MenuStyle", True, "MenuWidth", 4000
With Help1,"MenuStyle", True, "MenuWidth", 4000

Παρακάτω είναι οι ορισμοί όπως τους δίνουμε στο πρόγραμμα. Με τα mi$ και mr$ μαζεύουμε λίγο το κώδικα. Φτιάχνουμε  και MenuRadio (φαίνονται στην εικόνα). Επειδή το TAB δεν το ξέρει το σύστημα να μας το βγάλει με γράμματα, υπάρχει μια επιλογή legend που δηλώνουμε τι θα εμφανίζεται. Δείτε την εικόνα πώς εμφανίζεται. Στο τέλος κάθε ορισμού βάζουμε το MenuGroup. Αυτό κάνει τα βελάκια να μετακινούν την εστίαση στα στοιχεία μόνο του μενού. Τα τρια πρώτα φτιάχτηκαν χωρίς ID δηλαδή στο πρόγραμμα έχουν σειρά αριθμητική. Ομοίως έχει και το τέταρτο αλλά εδώ έβαλα από ένα όνομα στην ID ιδιότητα και έτσι ο κώδικας που στηρίζεται στο ID μπορεί να παραμείνει ως έχει ενώ θα μπουν άλλες γραμμές ενδιάμεσα στις υπάρχουσες. Αυτός είναι καλύτερος τρόπος, αλλά εδώ ήθελα να το δει κανείς,  για να κατανοήσει τι λέμε hardlink κώδικα. Στα τρια πρώτα μενού να θα θέλαμε να προσθέσουμε γραμμή ενδιάμεσα θα έπρεπε να πάμε στο κώδικα εξυπηρέτησης του γεγονότος του αντίστοιχου μενού και να αυξήουμε κατά ένα τους αριθμούς που αναφέρονται στις επιλογές κάτω από τη γραμμή εισαγωγής.

Στις προηγούμενες εκδόσεις υπήρχε ένα λάθος που δεν άφηνε να γράψουμε παραπάνω από δυο named arguments, ή ονόματα ορισμών κατά τη κλήση (δείτε ότι μετά το όνομα έχουν διπλό σύμβολο, το :=).

Όταν πατάμε ένα συνδυασμό, πχ το Ctrl+V, μενού Edit επιλογή Paste, ενώ η εστίαση είναι στο ΚΕΙΜΕΝΟ θα εκτελεστεί αυτό του κειμένου (που το "ακούει") και δεν θα εκτελεστεί αυτό του μενού, επειδή έχει προτεραιότητα αυτό το στοιχείο που έχει την εστίαση. Μπορούμε πχ να βλέπουμε ένα μενού έστω το File και να δώσουμε το Ctrl+V, τότε θα κλείσει το μενού και θα δούμε την επικόλληση να έχει γίνει!

Δείτε στις εντολές παρακάτω που είναι οι ορισμοί των διαχωριστικών γραμμών!

const mi$="MenuItem"
const mr$="MenuRadio"
Method File1, mi$,"Open",true, acc:="O", ctrl:=true
Method File1, mi$,"Save",true, acc:="S", ctrl:=true
Method File1, mi$,""    \\  only  a line here
Method File1, mi$,"Close",true, acc:="C", alt:=true
Method File1, mi$,"Quit",true, acc:="Q", alt:=true


With File1, "MenuGroup","This"


Method Edit1, mi$,"Cut",true, acc:="X", ctrl:=true
Method Edit1, mi$,"Copy",true, acc:="C", ctrl:=true
Method Edit1, mi$,"Paste",true, acc:="V", ctrl:=true
Method Edit1, mi$,""
Method Edit1, mi$,"Less Indent",true, acc:=9, ctrl:=true, shift:=true, legend:="TAB"
Method Edit1, mi$,"More Indent",true, acc:=9, ctrl:=true, legend:="TAB"
Method Edit1, mi$,""
Method Edit1, mr$,"Tabs for Indent",true,true , acc:="T", alt:=true
Method Edit1, mr$,"Spaces for Indent",true,false, acc:="S", alt:=true
Method Edit1, mi$,""
Method Edit1, mi$,"Show Hidden Characters", true, true, acc:="F10"
Method Edit1, mi$,"Free Style Edit", true, true, acc:="F9", shift:=True


With Edit1, "MenuGroup","This"


Method Run1, mi$,"Debug",true, acc:="F5", alt:=true
Method Run1, mi$,""
Method Run1, mi$,"Test Slow",true, acc:="F8", alt:=true
Method Run1, mi$,"Test Normal", true, acc:="F6", alt:=true
Method Run1, mi$,""
Method Run1, mi$,"Settings", acc:="U", ctrl:=true
Method Run1, mi$,"Default Folder", acc:="D", ctrl:=true
Method Run1, mi$,"Folder Documents", acc:="D", alt:=true


With Run1, "MenuGroup","This"


Method Help1, mi$,"About",true, id:="ABOUT" , acc:="A", alt:=true
Method Help1, mi$,""
Method Help1, mi$,"Find Topic",true ,ID:="FIND", acc:="F", alt:=true
Method Help1, mi$,"Open Topic",HelpShow ,ID:="OPEN", acc:="O", shift:=true, alt:=true
Method Help1, mi$,""
Method Help1, mi$,"Close Help",HelpShow ,ID:="CLOSE", acc:="C", ctrl:=true, shift:=true


With Help1, "MenuGroup","This"


Καλό Προγραμματισμό!
ΓΚ





Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.