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

Παράδειγμα με διαμόρφωση τμημάτων (decoration)

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

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

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

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

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

Ουσιαστικά σωρός τιμών είναι ένα ρεύμα εισόδου/εξόδου, ως μια στοίβα, από την οποία διαβάζουμε και στην οποία βάζουμε τιμές (με την Βάλε στην κορυφή της, ενώ με την Σειρά βάζουμε στο τέλος της, ή στο πυθμένα)
Το Βάλε 5, 3 θα βάλει τελικά το 3 στην κορυφή και το 5 ένα κάτω από την κορυφή.
Το Σειρά 4,2 θα βάλει το 2 στο τέλος και το 4 ένα από το τέλος (ή πυθμένα της στοίβας, ή σωρού τιμών όπως την λέμε στη Μ2000).

Ο σωρός τιμών έχει ενδιαφέροντα χαρακτηριστικά, μπορεί να πάρει αριθμούς, αλφαριθμητικά, αντικείμενα, και στα αντικείμενα μπορεί να είναι αντικείμενα σωροί επίσης. Μια απλούστευση της ιδέας του σωρού είναι ότι έχουμε μια γραμμική διάταξη στοιχείων με δυνατότητα μετακίνησης χωρίς κόστος. Βάζουμε και βγάζουμε με μεγάλη ευκολία! Εδώ δεν μας ενδιαφέρουν άλλα χαρακτηριστικά και δεν θα δούμε άλλα. Αυτό που μας ενδιαφέρει είναι ότι εντολές για το σωρό εκτελούνται σε αυτό που λέμε τρέχον σωρός τιμών. Η Μέγεθος.Σωρού μας λέει πόσα στοιχεία έχει ο σωρός (ένας πίνακας εγγράφεται στο σωρό ως ένα στοιχείο, ενώ μπορεί να έχει χιλιάδες), δηλαδή πόσα είναι διατεταγμένα σε αυτόν. Η εντολή Πέτα χωρίς όρισμα είναι ισοδύναμη με την Πέτα 1, και θα πετάξει την κορυφή και το αμέσως επόμενο θα γίνει η νέα κορυφή. Αν δεν υπάρχει όμως στοιχείο να πετάξει θα βγάλει λάθος. Η Πέτα 0 δεν βγάζει λάθος. Μπορεί να φαίνεται άχρηστο αλλά στη θέση του 0 μπορούμε να έχουμε αριθμητική παράσταση, και να προκύπτει πότε 0 ή πότε κάτι άλλο.

Η Αριθμός τραβάει τη κορυφή του σωρού τιμών, αν έχουμε αριθμός αλλιώς βγάζει λάθος. Η Γράμμα$ δίνει το αλφαριθμητικό στη κορυφή του σωρού αλλιώς βγάζει λάθος.

Όταν καλούμε ένα τμήμα έστω εδώ την Εμφάνιση με ορίσματα έστω το 5 και το 7 τότε ο διερμηνευτής βάζει αυτά σε ένα σωρό πρόσκαιρο, με την εντολή Σειρά, δηλαδή το 7 θα είναι τελευταίο και μετά κάνει ένωση σωρών, βάζοντας τον πρόσκαιρο στη κορυφή του τρέχοντος σωρού. Έτσι το 5 θα είναι στη κορυφή, μετά το 7 και μετά ότι ήδη υπήρχε στο σωρό.

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

Μετά φτιάχνουμε την ΝέαΕμφάνιση όπου εκεί βάζουμε και ένα στάδιο ακόμα, την προσαρμογή. Έχουμε μια Εμφάνισε εσωτερική που απευθείας δίνει τις παύλες όσο το μήκος στήλης εκτύπωσης στην οθόνη μας. Η Στήλη μας λέει πόσους χαρακτήρες έχει η στήλη. Αυτές καθορίζονται αυτόματα με την Φόρμα Χ, Υ αλλά μπορούμε να την αλλάξουμε, γιατί υπάρχει ως δεύτερη παράμετρος σε μια $(), μια εσωτερική συνάρτηση της Τύπωσε.

Στο παράδειγμα έχουμε το πρόσθετο τμήμα για προσαρμογή τιμών εισόδου, το οποίο διαβάζει αλφαριθμητικά και τα μετατρέπει σε αριθμούς, αλλά και άλλα όπως αυτό που μετατρέπει σε ακέραιες τιμές, καθώς και μια άλλη που κάνει στρογγυλοποίηση. Δεν είναι το ίδιο με τη προσαρμογή ακεραίου., διότι η Στρογγ(2.2, 0) στρογγυλοποιεί στο πενηνταράκι όπως λέμε ενώ ο Ακ() δίνει τον αμέσως μικρότερο ακέραιο.
Το Στρογγ(-2.2, 0) θα δώσει το -2, ενώ το Ακ(-2.2) θα δώσει το -3

Οι εικόνες είναι από linux με Wine. Αναφέρει ο διερμηνευτής ότι είναι Windows 7 επειδή αυτό δείχνει το Wine, και ορθώς αναφέρει ότι είναι 64bit το λειτουργικό γιατί 64bit είναι το Linux  στον υπολογιστή δοκιμής!
(ο χρωματισμός στον διορθωτή διαφέρει ανάλογα με το αν έχουμε σκούρο ή φωτεινό φόντο. Στην εξαγωγή σε Html (με απλή αντιγραφή στο πρόχειρο το κάνει) χρησιμοποιεί τον χρωματισμό που έχει οριστεί στις Ρυθμίσεις - υπάρχει τέτοια εντολή). Σε Linux την εξαγωγή σε html την διαβάζει το Libreoffice και το χρησιμοποιούμε ως ενδιάμεσο για να το ξανά αντιγράψουμε και μετά να το επικολλήσουμε στο Blogger εδώ, ενώ σε Windows δεν θέλουμε ενδιάμεσο.

Ο διορθωτής φαίνεται περιορισμένος στο κάτω τμήμα (ολίσθησης). Αν δώσουμε Οθόνη , 0 τότε η ολίσθηση θα πιάσει όλη την οθόνη και θα ανοίξει το παράθυρο του διορθωτή σε όλη την οθόνη (δεν γράφει πάνω στην οθόνη, αλλά σε δικό του χώρο, οπότε με Esc γυρνάμε στη κονσόλα και βλέπουμε ότι είχε). Με Οθόνη , -10 δηλαδή με αρνητικό το δεύτερο νούμερο λέμε να έχουμε ολίσθηση στις δέκα τελευταίες γραμμές, άρα δίνουμε δέκα γραμμές στον διορθωτή μαζί με την επικεφαλίδα (το πρώτο δεν το δίνουμε εδώ και είναι το χρώμα φόντου)
Με Ctrl +C  καθαρίζουμε την κονσόλα (είναι ίδιο με το CLS ή Οθόνη)




Τμήμα Εμφάνιση {
      Γενική Κ=Αληθές
      Τμήμα τρόπος {
            Αν Μέγεθος.Σωρού>=2 Τότε Πέτα Μέγεθος.Σωρού-2
            Κ<=Ψευδές
      }
      τρόπος
      \\ το $(4)  βάζει αναλογική γραφή. το $(0) επαναφέρει σε μη αναλογική
      Αν Κ Τότε {
            Τύπωσε $("0.00"), $(4), Αριθμός
            Τύπωσε $(""),$(0),
      } Αλλιώς {
            Τύπωσε Επαν$("-", Στήλη)
      }
}

Εμφάνιση 10,2
Τμήμα Διαίρεση (χ,υ) {
      αν υ==0 Τότε Βάλε 0 : έξοδος
      Βάλε χ/υ
}
Τμήμα Γινόμενο (χ,υ) {
      Βάλε χ*υ
}
Τμήμα Διαφορά (χ, υ) {
      Βάλε χ-υ
}
Τμήμα Σούμα (χ,υ) {
      Βάλε χ+υ
}
Εμφάνιση 5, 7 ; τρόπος ως διαίρεση
Εμφάνιση 5, 7 ; τρόπος ως γινόμενο
Εμφάνιση 5, 7 ; τρόπος ως διαφορά
Εμφάνιση 5, 7 ; τρόπος ως σούμα
Τμήμα ΑριθμοίΩςΧαρακτήρες {
      Διάβασε α$, β$
      Βάλε Τιμή(β$),Τιμή(α$)
}
Τμήμα ΝέαΕμφάνιση {
      Τμήμα Προσαρμογή {}
      Τμήμα Εμφάνιση {
            Τύπωσε Επαν$("-", Στήλη)
      }
      Προσαρμογή
      Εμφάνιση ; τρόπος
}
ΝέαΕμφάνιση "5", "7" ; Εμφάνιση, τρόπος ως σούμα, προσαρμογή ως ΑριθμοίΩςΧαρακτήρες
ΝέαΕμφάνιση 5, 7 ; Εμφάνιση, τρόπος ως γινόμενο
Τμήμα ΕμφάνισηΩςΧαρακτήρες {
      Γενική Κ=Αληθές
      Τμήμα τρόπος {
            Αν Μέγεθος.Σωρού>=2 Τότε Πέτα Μέγεθος.Σωρού-2
            Κ<=Ψευδές
      }
      τρόπος
      Αν Κ Τότε {
            Τύπωσε $(4),Γραφη$(Αριθμός, "0.00")
            Τύπωσε $(0),
      } Αλλιώς {
            Τύπωσε Επαν$("-", Στήλη)
      }
}
ΝέαΕμφάνιση 5, 7 ; Εμφάνιση ως ΕμφάνισηΩςΧαρακτήρες, τρόπος ως διαίρεση
Τμήμα Ακέραιοι {
      Διάβασε χ, υ
      Βάλε Ακ(υ), Ακ(χ)
}
Τμήμα ΑκέραιοιΜεΣτρογγυλοποίηση {
      Διάβασε χ, υ
      Βάλε Στρογγ(υ,0), Στρογγ(χ,0)
}
ΝέαΕμφάνιση 5.5, 7.8 ; Εμφάνιση, τρόπος ως σούμα, προσαρμογή ως ακέραιοι
ΝέαΕμφάνιση 5.5, 7.8 ; Εμφάνιση, τρόπος ως σούμα, προσαρμογή ως ΑκέραιοιΜεΣτρογγυλοποίηση
ΝέαΕμφάνιση 5.5, 7.8 ; Εμφάνιση, τρόπος ως σούμα
Τμήμα ΕμφάνισηΜεΜονάδες {
      Γενική Κ=Αληθές
      Τμήμα τρόπος {
            Αν Μέγεθος.Σωρού>=2 Τότε Πέτα Μέγεθος.Σωρού-2
            Κ<=Ψευδές
      }
      τρόπος
      Αν Κ Τότε {
            Τύπωσε $(7),Γραφη$(Αριθμός, "0.00 ")+Γράμμα$
            Τύπωσε $(0),
      } Αλλιώς {
            Τύπωσε Επαν$("-", Στήλη)
      }
}
ΝέαΕμφάνιση
ΝέαΕμφάνιση 5,7, "Km" ; Εμφάνιση ως ΕμφάνισηΜεΜονάδες, τρόπος ως γινόμενο
ΝέαΕμφάνιση 5,7, "Km" ; Εμφάνιση ως ΕμφάνισηΜεΜονάδες, τρόπος ως σούμα
ΝέαΕμφάνιση

Αναθεώρηση 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 τότε με τα βελάκια άνω και κάτω επιλέγουμε μια εντολή (μια παράγραφο που μπορεί να έχει εντολές η μία μετά την άλλη με διαχωρισμό με άνω και κάτω τελεία)

Δευτέρα, 22 Μαΐου 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).


' 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 exit
}
Threads erase
Declare form1 nothing
Declare form3 nothing
Declare cairo nothing
declare New_c nothing
Show

Νέα έκδοση 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"


Τρίτη, 16 Μαΐου 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"