// MMII main module, declares the interfaces that are available for // application writers // The application framework is vaguely a Model-View-Controller-Listener // Models are the concrete implementations of Application, Dialog, Widget, // etc. // Views are the native-code widgets // Controllers are the code implemented in user applications // Listeners are callback objects also implemented in user applications. // it will often be the case that the controllers and listeners will // be one and the same objects // Brush is used by the Canvas and the CanvasPainter uses Brush.Brush makeApplication(name:string):Application interface Application { //addListener(x:ApplicationListener) //removeListener(x:ApplicationListener) addIdleTask(t:IdleTask) removeIdleTask(t:IdleTask) run() //dispatch window messages and run idle tasks as necessery requestApplicationExit() //call this from listeners to request an application exit /*-1 for width and/or height means use a system default value in that dimension. */ makeFrame(title:string, width:int, height:int):Frame } interface IdleTask { work(x:Application) } interface Frame { composite():Composite addListener(x:FrameListener) removeListener(x:FrameListener) } interface FrameListener { /*return false if you don't want to allow window to close*/ onClose(x:Frame):bool } interface Widget { isComposite():bool parent():Composite } interface Composite extends Widget { /*You may only call one method of the WidgetMaker it will return null and perform a noop if any method is called more than once. retaining a handle to a WidgetMaker is pretty useless.*/ addWidget(x:int, y:int, w:int, h:int):WidgetMaker enumerateChildren(c:CompositeVisitor) destroy() } interface CompositeVisitor { visitChild(c:Composite, x:Widget) } /*construct the specified widget into the owning composite, and return a handle to the widget */ interface WidgetMaker { composite():Composite command(label:string):Command /*null label is ok for choices*/ multipleChoice():MultipleChoice textEntry():TextEntry canvas():Canvas } interface Command extends Widget { getLabel():string setLabel(l:string) addListener(x:CommandListener) removeListener(x:CommandListener) } interface CommandListener { onClick(x:Command) } interface MultipleChoice extends Widget { /*returns position of choice*/ addChoice(label:string, datum:object):int getLabel(pos:int):string getDatum(pos:int):object /*returns the old datum, null if none */ setDatum(pos:int, datum:object):object setLabel(pos:int, label:string):string enumerateChoices(v:MultipleChoiceVisitor) getSelected():int /*returns old selected, or -1 if none*/ setSelected(pos:int):int addListener(v:MultipleChoiceListener) removeListener(v:MultipleChoiceListener) } interface MultipleChoiceVisitor { visitChoice(m:MultipleChoice, pos:int, label:string, datum:object) } interface MultipleChoiceListener { onChange(x:MultipleChoice, pos:int) } interface TextEntry extends Widget{ getText():string setText(s:string) //listeners are notified of text changes by the user addListener(v:TextEntryListener) removeListener(v:TextEntryListener) } interface TextEntryListener { onChange(t:TextEntry) } interface Canvas extends Widget { //paint the window _now_ using the given CanvasPainter paint(p:CanvasPainter) //repaint the window when necessery, // returns the old CanvasPainter if any // passing null turns off updating setUpdatePainter(p:CanvasPainter):CanvasPainter getUpdatePainter():CanvasPainter } interface CanvasPainter { //don't try to stash the Brush from this method -- bad things // WILL happen paint(c:Canvas, b:Brush) }