hodza/BlackBox.Shkola.2014 huggingface dataset:
Obx/Docu/Excel.odc

Overview by Example: ObxExcel

This example how the OLE Automation controller subsystem can be used to program Microsoft Excel. Use the following menu entries to run the examples:

	"Show Excel"	""	"ObxExcel.ShowExcel"	""
	"Read Excel"	""	"ObxExcel.ReadExcel"	"StdCmds.SingletonGuard"
	"Open Chart"	""	"ObxExcel.OpenChart"	"StdCmds.SingletonGuard"

ShowExcel adds different values to a new worksheet and opens the worksheet as an OLE object in a BlackBox text.
ReadExcel reads a selected worksheet object and writes the contents of the cells into the log.
OpenChart uses the values in a selected worksheet object and opens a corresponding chart in a separate Excel window.

See also the CtlDeveloperManual.

ObxExcelsources
Obx/Docu/Fact.odc

Oberon by Example: ObxFact

This example demonstrates the use of module Integers, which implements arbitrary precision integers. The example implements the command ObxFact.Compute, which computes the factorial of an integer selected as text in a text view, and replaces the selection with the result.

Example:
	25	->	15511210043330985984000000
	
Note: The time required to compute a factorial grows exponentially with the size of the input. For numbers greater than 500 a considerable time will be needed.

ObxFactsources
Obx/Docu/Fern.odc

Overview by Example: Fractal Fern
(Example from "Programming in Oberon", by Wirth/Reiser)

1) Compile module ObxRandom

2) Compile module ObxFern

3) Select the following numbers:

	120	0	25
	0.0	0.85	0.2	-0.15
	0.0	0.04	-0.26	0.28
	0.0	-0.04	0.23	0.26
	0.16	0.85	0.22	0.24
	0.0	0.0	0.0	0.0
	0.0	1.6	1.6	0.44
	0.01	0.85	0.07	0.07

4) Execute the following command:  ObxFern.Init

5) Execute the following command:  ObxFern.Draw

6) Stop the iteration by pressing the key "s"
Obx/Docu/FileTree.odc

Overview by Example: ObxFileTree

This example illustrates the use of the TreeControl. The aim is to create a file browser similar to the Windows Explorer. To keep it simple, the user interface will consist of a text field, three buttons, and a TreeControl. When the user types a path to a directory in the text field and clicks on the Display button the files and folders in the given directory are shown in the tree. The user can browse the files and folders in the tree, and a double click on a file opens the file in BlackBox.

The Interactors
To achieve this user interface we need a Dialog.String variable to connect to the text field, we need two procedures to connect to the Display and Open buttons respectively, and we need a Dialog.Tree variable to connect to the TreeControl. We also need a notifier to connect to TreeControl. This notifier should detect a double click on a leaf in the tree and open the corresponding file.

The TreeControl has several properties which can be modified with the property inspector. For this example the default properties are sufficient. In particular the option "Folder icons" should be switched on. This option makes the TreeControl show icons in front of each node in the tree. The leaf nodes get a "file" icon and the nodes that have subnodes get a "folder" icon. This option gives our program the same look and feel as the Windows Explorer.

The only problem is that if a file directory does not contain any files it will be a leaf node and thus look like a file and not a folder. For this purpose the Dialog.TreeNode offers a method called ViewAsFolder, which makes a node in a tree display a folder icon even if it doesn't have any subnodes.

The Implemantation
To implement this, this example uses four procedures:

PROCEDURE BuildDirTree (loc: Files.Locator; parent: Dialog.TreeNode);
PROCEDURE Update*;
PROCEDURE Open*;
PROCEDURE OpenGuard* (VAR par: Dialog.Par);

BuildDirTree recursively adds files and folders to the tree, and also makes sure that the ViewAsFolder attribute is set for nodes that are folders. Update is the procedure that is connected to the Display command button in the user interface. This procedure clears the tree and then calls BuildDirTree. The procedure Open opens the selected folder or file. StdCmds.DefaultOnDoubleClick, which is set as the TreeControl's notifier procedure, executes the default command Open when the TreeControl is double-clicked.

 "StdCmds.OpenToolDialog('Obx/Rsrc/FileTree', 'ObxFileTree Demo')"

ObxFileTreesources
Obx/Docu/Hello1.odc

Overview by Example: ObxHello1

Everything in the BlackBox Component Framework revolves around views. A view is a rectangular part of a document; a document consists of a hierarchy of nested views. What you are now looking at is a text view; below is another text view embedded in it:

	MODULE ObxHello1;

	IMPORT Views, TextModels, TextMappers, TextViews;

	PROCEDURE Do*;
		VAR t: TextModels.Model; f: TextMappers.Formatter; v: TextViews.View;
	BEGIN
		t := TextModels.dir.New();	(* create a new, empty text object *)
		f.ConnectTo(t);	(* connect a formatter to the text *)
		f.WriteString("Hello World"); f.WriteLn;	(* write a string and a 0DX into new text *) 
		v := TextViews.dir.New(t);	(* create a new text view for t *)
		Views.OpenView(v)	(* open the view in a window *)
	END Do;

END ObxHello1.


  ObxHello1.Do

The embedded text view above contains a slightly more advanced hello world program than ObxHello0. It doesn't use module StdLog to write into the log window. Instead, it creates a new empty text, to which it connects a text formatter. A text formatter is an object which provides procedures to write variables of all basic Component Pascal types into a text. In the above example, a string and a carriage return are written to the text, which means that they are appended to the existing text. Since a newly created text is empty, t now contains exactly what the formatter has written into it.

A text is an object which carries text and text attributes; i.e., a sequence of characters and information about font, color, and vertical offset of each character. However, a text does not know how to draw itself; this is the purpose of a text view. (Yes, what you are currently looking at is the rendering of such a view.) When a text view is created, it receives the text to be displayed as a parameter. Several views can be open on the same text simultaneously. When you edit in one view, the changes are propagated to all other views on the same text.

When you create a text, you perform the steps outlined below:

1) create a text model
2) connect a text formatter to it
3) write the text's contents via the formatter
4) create a text view for the model
5) open the text view in a window

In this example, we have seen how to use the text subsystem in order to create a new text.
Obx/Docu/Links.odc

Overview by Example: ObxLinks

This example demonstrates how a text can be created which contains link views. The text represents the contents of a directory. There is a link for each subdirectory, and a link for each file that can be converted into a view. Thus this example also demonstrates how files and locators are enumerated and how file converters are used.

 "ObxLinks.Directory('')"

ObxLinkssources
Obx/Docu/Omosi.odc

Overview by Example: ObxOmosi

			
	
Further examples:
Omosi1	Omosi2	Omosi3	Omosi4	Omosi5	Omosi6

An Omosi view consists of an area filled with triangles. Each of these triangles may take on one of four colors. By clicking on a triangle, it changes it color. By shift-clicking, several triangles can be selected, which will change colors simultaneously. By clicking on a triangle with the modifier key held down, a color palette dialog pops up which allows to map this color state to another RGB color.

ObxOmosisources

 "ObxOmosi.Deposit; StdCmds.Open"
Obx/Docu/Open0.odc

Overview by Example: ObxOpen0

This example asks the user for a file, opens the document contained in the file, and appends a string to the text contained in the document. Finally, the text (in its text view) is opened in a window.

	MODULE ObxOpen0;

	IMPORT Files, Converters, Views, TextModels, TextMappers, TextViews;

	PROCEDURE Do*;
		VAR loc: Files.Locator; name: Files.Name; conv: Converters.Converter;
			v: Views.View; t: TextModels.Model; f: TextMappers.Formatter;
	BEGIN
		loc := NIL; name := ""; conv := NIL;	(* no defaults for Views.Old *)
		v := Views.Old(Views.ask, loc, name, conv);	(* ask user for a file and open it as a view *)
		IF (v # NIL) & (v IS TextViews.View) THEN		(* make sure it is a text view *)
			t := v(TextViews.View).ThisModel();	(* get the text view's model  *)
			f.ConnectTo(t);
			f.SetPos(t.Length());	(* set the formatter to the end of the text *)
			f.WriteString("appendix");	(* append a string *)
			Views.OpenView(v)	(* open the text view in a window *)
		END
	END Do;

END ObxOpen0.

After compilation, you can try out the above example:

  ObxOpen0.Do

With this example, we have seen how the contents of a document's root view can be accessed, and how this view can be opened in a window after its contents have been modified. In contrast to ObxHello1, an existing text has been modified; by first setting the formatter to its end, and then appending some new text.

Note that similar to the previous examples, views play a central role.

In contrast to traditional development systems and frameworks, files, windows, and applications play only a minor role in the BlackBox Component Framework, or have completely disappeared as abstractions of their own. On the other hand, the view has become a pivotal abstraction. It is an essential property of views that they may be nested, to form hierarchical documents.

These aspects of the BlackBox Component Framework constitute a fundamental shift
  from monolithic applications to software components
  from interoperable programs to integrated components
  from automation islands to open environments
  from application-centered design to document-centered design
Obx/Docu/Open1.odc

Overview by Example: ObxOpen1

This example is a variation of the previous one; instead of opening a view it stores it back in some file.

	MODULE ObxOpen1;

	IMPORT Converters, Files, Views, TextModels, TextMappers, TextViews;

	PROCEDURE Do*;
		VAR loc: Files.Locator; name: Files.Name; conv: Converters.Converter;
			v: Views.View; t: TextModels.Model; f: TextMappers.Formatter;
			res: LONGINT;
	BEGIN
		loc := NIL; name := ""; conv := NIL;
		v := Views.Old(Views.ask, loc, name, conv);
		IF (v # NIL) & (v IS TextViews.View) THEN
			t := v(TextViews.View).ThisModel();
			f.ConnectTo(t);
			f.SetPos(t.Length());
			f.WriteString("appendix");
			Views.Register(v, Views.ask, loc, name, conv, res) (* ask the user where to save the document *)
		END
	END Do;

END ObxOpen1.

  ObxOpen1.Do

In this example we have seen how a view can be stored into a file.
Obx/Docu/Orders.odc

Overview by Example: ObxOrders

ObxOrders is a more realistic example of a program which uses forms for data entry and data manipulation. It lets the user enter new orders, browse through existing orders, and save all orders into a file, or load them from a file. A dialog always shows the current order. For this order, an invoice text can be generated, ready to be printed.
	The order data is stored in a very simple main memory database: each order is represented as a record, and the orders are connected in a doubly-linked ring with a dummy header element. One element of a ring thus contains a next and a prev pointer, as well as the data of one order. In this case, the data is directly represented as a variable of the interactor type which is used for data entry. Note that this approach is only possible in very simple cases; normally an interactor would only represent a subset of a tuple stored in the database, and the database representation would be independent of any specific interactor.
	The other aspect of our example program which is simpler than in typical applications is that the database is global: the doubly-linked ring is anchored in a global variable, so there is at most one order database open at any given point in time.

This example has four noteworthy aspects: The procedure NewRuler shows how a new text ruler with specific properties can be created, and in procedure Invoice it can be seen how the text font style can be changed to bold and back to normal when creating a text.
	Thirdly, the dialog uses guard commands to disable and enable controls in the dialog: Depending on whether there currently is an open database, the data entry, invoice generation, etc. controls are enabled, otherwise disabled. Depending on whether the current order is the last (first) one, the Next (First) button is disabled, otherwise enabled.
	Fourth, the formatter procedure WriteView is used twice to insert a view into the text: first a ruler view is written, and a bit later a standard clock view is written to the text.

ObxOrderssources

Maindialog

"Delete"dialog

 "StdCmds.OpenAuxDialog('Obx/Rsrc/Orders', 'Order Processing')"

In Obx/Samples/Odata there is some sample data.
Obx/Docu/ParCmd.odc

Overview by Example: ObxParCmd

This example shows how a command button's context can be accessed. For example, a button in a text may invoke a command, which reads the text immediately following the command. This text can be used as an input parameter to the command.

ObxParCmd implements two commands which scan the text behind a command button for a string. In the first command, the string is written to the log:

 "this is a string following a command button"

In this way, tool texts similar to the tools of the original ETH Oberon can be constructed.

In the second example, the string following the button is executed as a command, thus operating in a similar way as a commander (-> DevCommanders):

 "DevDebug.ShowLoadedModules"

ObxParCmdsources
Obx/Docu/Patterns.odc

Overview by Example: ObxPatterns

This view displays a series of concentric rectangles. The view contains no special state; its display is completely determined by its current size alone.

The view implementation is very simple. However, there are three aspects of this program which are noteworthy:

First, although the view has no state, it still extends the Internalize and Externalize procedures bound to type View. This is done only in order to store a version number of the view. It is strongly recommended to store such a version number even in the simplest of views, in order to provide file format extensibility for future versions of the view implementation.

Second, the view contains no special state of its own. However, its display may differ, depending on its current size. A view does not manage its own size, since its size is completely determined by the context in which the view is embedded. A view can determine its current size by asking its context via the context's GetSize procedure.

Third, while a view's size is completely controlled by its context, the context still may (but need not!) cooperate when the size is determined. For example, when a view is newly inserted into a container, the container may ask the view for its preferred size; or when it wants to change the embedded view's current size, it may give the view the opportunity to define constraints on its size, e.g., by limiting width or height to some minimal or maximal values. The container can cooperate by sending a size preference (Properties.SizePrefs) to the embedded view, containing the proposed sizes (which may be undefined). The view thus gets the opportunity to modify these values to indicate its preferences.

ObxPatternssources

 "ObxPatterns.Deposit; StdCmds.Open"

Note: in order to change the pattern view's size, first select it using command Edit->Select Document, then manipulate one of the resize handles.
Obx/Docu/PhoneDB.odc

Overview by Example: ObxPhoneDB

This example is described in chapter3 of the BlackBox tutorial.


DEFINITION ObxPhoneDB;

	TYPE String = ARRAY 32 OF CHAR;

	PROCEDURE LookupByIndex (index: INTEGER; OUT name, number: String);
	PROCEDURE LookupByName (name: String; OUT number: String);
	PROCEDURE LookupByNumber (number: String; OUT name: String);

END ObxPhoneDB.


Module ObxPhoneDB provides access to a phone database. Access may happen by index, by name, or by number. An entry consists of a name and a phone number string. Neither may be empty. The smallest index is 0, and all entries are contiguous.


PROCEDURE LookupByIndex (index: INTEGER; OUT name, number: ARRAY OF CHAR)
Return the <name, number> pair of entry index. If the index is too large, <"", ""> is returned.
The procedure operates in constant time.

Pre
index >= 0	20

Post
index is legal
	name # ""  &  number # ""
index is not legal
	name = ""  &  number = ""

PROCEDURE LookupByName (name: ARRAY OF CHAR; OUT number: ARRAY OF CHAR)
Returns a phone number associated with name, or "" if no entry for name is found.
The procedure operates in linear time, depending on the size of the database.

Post
name found
	number # ""
name not found
	number = ""

PROCEDURE LookupByNumber (number: ARRAY OF CHAR; OUT name: ARRAY OF CHAR)
Returns the name associated with number, or "" if no entry for number is found.
The procedure operates in linear time, depending on the size of the database.

Post
number found
	name # ""
number not found
	name = ""
Obx/Docu/Pi.odc

Oberon by Example: ObxPi

This example demonstrates the use of module Integers for computing with arbitrary precision decimals. The example implements the command ObxPi.WritePi, which computes n decimal digits of the constant Pi and writes the result into the log. The command ObxPi.Pi only computes Pi, without printing the result. It can be used to measure the efficiency of the arbitrary precision integer package.

For computation, the rule

	 Pi = 16 * atan(1/5) - 4 * atan(1/239)

is used where atan is approximated with its Taylor series expansion at x = 0:

		atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... 

The computation is performed with integers only. Each decimal x is represented as integer x * 10^d where d is the number of decimal digits to the right of the decimal point. Arithmetic operations on decimals are performed using integer arithmetic. This way, the results are chopped, not rounded. For each operation, an error of at most one ulp may be introduced. Therefore, the computation of Pi is performed with some guard digits. The final result is chopped to the desired number of decimal digits. If you want to compute more digits of Pi you have to increase the number of guard digits. Use Ceiling(Log10(1.43*n)) guard digits in order to compute n digits of Pi.

Example:
 "ObxPi.WritePi(1000)"

31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989

ObxPisources
Obx/Docu/RatCalc.odc

Oberon by Example: ObxRatCalc

This example implements a simplifier for rational numbers of arbitrary precision. Expressions to be simplified are built up from integer numbers, the operators "+", "-", "*", "/", "^", and parentheses. Exponents ("^") must be integer numbers and their absolute value must not exceed MAX(INTEGER).
The result is either an integer or a rational number (command ObxRatCalc.Simplify), or a floating point number (ObxRatCalc.Approximate).
The implementation of ObxRatCalc uses the Integersmodule, which provides a data type for arbitrary precision integers and operations on them. The calculator works on arithmetic expressions, such as the following:

Source Expression		ObxRatCalc.Simplify		ObxRatCalc.Approximate

((100 + 27 - 2) / (-5 * (2 + 3))) ^ (-3)	=	-1 / 125	=	-8*10^-3
999999999 * 999999999 / 81	=	12345678987654321
1234567890 / 987654321	=	137174210 /  109739369	= 1.2499999886093750001423828...
30.2 + 60.5	=	907 / 10	=	90.7

Note that the undo/redo mechanism can be used after an evaluation.

Syntax of input:

	expression := ["-"] {term addop} term.
	term := {factor mulop} factor.
	factor := ("(" expression ")" | integer) ["^" factor].
	integer := digit {digit} [ "." digit {digit} ].
	addop := "+".
	mulop := "*" | "/".

Menu entries in "Obx" menu:
	"Simplify"	""	"ObxRatCalc.Simplify"	"TextCmds.SelectionGuard"
	"Approximate"	""	"ObxRatCalc.Approximate"	"TextCmds.SelectionGuard"

ObxRatCalcsources
Obx/Docu/Tabs.odc

Overview by Example: ObxTabs

This example demonstrates a simple text transformation: the first, second and seventh tab character in each text line, starting from the beginning of a text selection, is transformed into a blank. Actually, this command was used to prepare some of the addresses to which the first issue of The Oberon Tribune was sent.

ObxTabssources

To use the command, select the beginning of the address list (i.e., the "Mr.	Alan..." string) and then click on the commander below:

 ObxTabs.Convert

Mr.	Alan	Taylor	Moon, Inc.	EDP department	Upping Street 10	23987	Surlington	Lunaland
Ms.	Dianna	Gloor	Future SW Corp.	Marketing	Manhatten Blvd.	93842	Powderdale	Otherland
Obx/Docu/TabViews.odc

Overview by Example: ObxTabViews

The property inspector for StdTabViews supplies a graphical user interface for creating and editing StdTabViews. This user interface is sufficient for most applications. However, if tabs need to be added and removed dynamically during runtime, the programming interface of StdTabViews needs to be used.

This example creates a StdTabViews.View with three tabs to start with. Then new tabs can be added or the selected tab can be deleted in runtime. Any kind of views can be added to a StdTabViews.View. In this example one ObxCube-view is added and the same ObxCalc-view is added several times. This shows another charactaristic of StdTabViews; when a view is added it is copied. Eventhough the same view is used to create several tabs, they all have their own view internally. You can easily try this by typing a number into a calculator view, then changing tab to another calculator view and type in another number. When you switch back to the first calculator it still displays the first number.

The example also installs a simple notifier which simply displays the notify message in the log.

Here you can try the example:
 "ObxTabViews.Deposit; StdCmds.Open"

To add a new calculator view, use this command:
 ObxTabViews.AddNewCalc

To delete the selected tab, use this command:
 ObxTabViews.DeleteTab

ObxTabViewssources
Obx/Docu/Tickers.odc

Overview by Example: ObxTickers

This example implements a simple stock ticker. The curve which is displayed shows a random walk. The black line is the origin, at which the walk started. If the curve reaches the upper or lower end of the view, then the origin is moved accordingly.

			

What this example shows is the use of actions. Services.Actions  are objects whose Do  procedures are executed in a delayed fashion, when the system is idle. An action which re-installs itself whenever it is invoked as in this example operates as a non-preemptive background task.

 "ObxTickers.Deposit; StdCmds.Open"

ObxTickerssources