% Simple graphics package with multiple inheritance % Multiple inheritance design taken from Bertrand Meyer's % book Object-Oriented Software Construction % Author: Peter Van Roy % Load QTk GUI tool from Mozart Standard Library declare [QTk]={Module.link ["x-oz://system/wp/QTk.ozf"]} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% declare % Composite figure % 1. LinkedList class % Header node (marker, not part of list): @elem==null % Last element: @next==null % List empty: @elem==null and @next==null class LinkedList attr elem next meth init(elem:E<=null next:N<=null) elem:=E next:=N end meth add(E) next:={New LinkedList init(elem:E next:@next)} end meth forall(P) if @elem\=null then {P @elem} end if @next\=null then {@next forall(P)} end end meth isempty($) @next==null end end % 2. Figure class class Figure meth otherwise(M) raise inexistingMethodError end end end class Circle from Figure attr canvas x y r meth init(Canvas X Y R) canvas:=Canvas x:=X y:=Y r:=R end meth move(X Y) x:=@x+X y:=@y+Y end meth display {@canvas create(oval @x-@r @y-@r @x+@r @y+@r)} end end class Line from Figure attr canvas x1 y1 x2 y2 meth init(Canvas X1 Y1 X2 Y2) canvas:=Canvas x1:=X1 y1:=Y1 x2:=X2 y2:=Y2 end meth move(X Y) x1:=@x1+X y1:=@y1+Y x2:=@x2+X y2:=@y2+Y end meth display {@canvas create(line @x1 @y1 @x2 @y2)} end end % 3. CompositeFigure class (with multiple inheritance) % With this design, a figure can consist of other figures, % some of which consist of other figures, and so forth, % to any number of levels class CompositeFigure from Figure LinkedList meth init LinkedList,init end meth move(X Y) {self forall(proc {$ F} {F move(X Y)} end)} end meth display {self forall(proc {$ F} {F display} end)} end end proc {DrawInit Canvas} Desc=td(title:"Simple graphics package" canvas(width:250 height:150 bg:white handle:Canvas)) Window={QTk.build Desc} in {Window show} end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Example /* declare Canvas={DrawInit} L1={New Line init(Canvas 50 50 150 50)} L2={New Line init(Canvas 150 50 100 125)} L3={New Line init(Canvas 100 125 50 50)} C1={New Circle init(Canvas 100 75 20)} F1={New CompositeFigure init} {F1 add(L1)} {F1 add(L2)} {F1 add(L3)} {F1 add(C1)} {F1 display} for I in 1..10 do {F1 display} {F1 move(3 ~2)} end */