Controllers
Controllers do the work of converting ezui instructions into user-facing objects.
To use ezui, your ezui content must be defined in a subclass of one of these controllers. The controller classes will make the connections between your code and the user-facing objects. You implement your interface construction and deconstruction in a standard series of methods:
buildThis will be called when it is time to build the interface components. This method is required.startedThis will be called when the interface is presented to the user. This method is optional.destroyThis will be called when the interface is destroyed. This method is optional.
The controllers listed here are fully compatible with Subscriber defined in mojo.subscriber. When using these controllers with Subscriber, you must use the class order Subscriber, OneOfTheControllerClasses. If the order is flipped, the Subscriber initialization will not be done properly and your subscription methods will not be called when events take place.
WindowController
- class ezui.WindowController(*args, **kwargs)
A controller for windows.
import ezui class DemoController(ezui.WindowController): def build(self): content = """ (Button) @button [_Text_] @textField """ self.w = ezui.EZWindow( title="Demo", content=content, controller=self ) def started(self): self.w.open() def buttonCallback(self, sender): print("The button was pushed.") def textFieldCallback(self, sender): print("The text field was edited.") DemoController()
- startProgress(text=None, maxValue=None, parent=None)
Start a progress bar. This returns an instance of
ProgressWindow.textText to show. Optional.maxValueThe maximum value for the bar. If this isNonethe bar will show a looping animation.parentA parent window to attach the progress window to. Optional.import AppKit import ezui class DemoController(ezui.WindowController): def build(self): content = """ (startProgress) @startProgressButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.startProgressButtonCallback(None) def startProgressButtonCallback(self, sender): self.progressWindow = self.startProgress( text="Optional text.", maxValue=20, parent=self.getWindow() ) self.progressCount = 0 self.timer = AppKit.NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( 0.25, self, "_incrementProgressBar:", None, True ) def _incrementProgressBar_(self, timer): if self.progressCount == 20: self.timer.invalidate() self.progressWindow.close() self.progressWindow = None else: self.progressWindow.increment() self.progressCount += 1 DemoController()
- showMessage(messageText, informativeText='', callback=None, alertStyle='informational', icon=None, helpCallback=None)
Show a message.
messageTextA short message.informativeTextA complete description. Optional.alertStyleThe style for the alert. Optional. Options:"informational""critical"
callbackA function to be called when the message is closed.iconANSImageto display instead of the default icon. Optional.helpCallbackA callback to be called when the help button is pressed.import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showMessage) @showMessageButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showMessageButtonCallback(None) def showMessageButtonCallback(self, sender): self.showMessage( messageText="This is message text.", informativeText="This is optional informative text.", helpCallback=self.helpButtonCallback ) def helpButtonCallback(self): print("The help button was pressed.") DemoController()
- showAsk(messageText, buttonTitles, informativeText='', callback=None, alertStyle='informational', icon=None, helpCallback=None)
Show a dialog with options for the user to choose from.
messageTextA short message.buttonTitlesA list of button titles. These are formatted as dicts with the following structure:{ "title" : "Text to be displayed.", "returnCode" : "Value to be returned by the button." }
informativeTextA complete description. Optional.alertStyleThe style for the alert. Optional. Options:"informational""critical"
callbackA function to be called when the message is closed.iconANSImageto display instead of the default icon. Optional.helpCallbackA callback to be called when the help button is pressed.import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showAsk) @showAskButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showAskButtonCallback(None) def showAskButtonCallback(self, sender): self.showAsk( messageText="This is message text.", informativeText="This is optional informative text.", buttonTitles=[ dict(title="A?", returnCode="A"), dict(title="B?", returnCode="B"), dict(title="C?", returnCode="C") ], callback=self.showAskResultCallback, helpCallback=self.helpButtonCallback ) def showAskResultCallback(self, value): print(f"showAsk result: {value}") def helpButtonCallback(self): print("The help button was pressed.") DemoController()
- showAskYesNo(messageText, informativeText='', callback=None, alertStyle='informational', icon=None, helpCallback=None)
Show a dialog with options “Yes” and “No” options for the user to choose from.
messageTextA short message.informativeTextA complete description. Optional.alertStyleThe style for the alert. Optional. Options:"informational""critical"
callbackA function to be called when the message is closed.iconANSImageto display instead of the default icon. Optional.helpCallbackA callback to be called when the help button is pressed.import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showAskYesNo) @showAskYesNoButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showAskYesNoButtonCallback(None) def showAskYesNoButtonCallback(self, sender): self.showAskYesNo( messageText="This is message text.", informativeText="This is optional informative text.", callback=self.showAskYesNoResultCallback, helpCallback=self.helpButtonCallback ) def showAskYesNoResultCallback(self, value): print(f"showAskYesNo result: {value}") def helpButtonCallback(self): print("The help button was pressed.") DemoController()
- showGetFolder(callback, messageText=None, directory=None, allowsMultipleSelection=False, accessoryView=None, descriptionData={})
import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showGetFolder) @showGetFolderButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showGetFolderButtonCallback(None) def showGetFolderButtonCallback(self, sender): accessoryViewContents = """ = TwoColumnForm : Letter: (A ...) @getFolderLetterPopUpButton : Number: (X) 0 @getFolderNumberRadioButtons ( ) 1 ( ) 2 """ accessoryViewDescriptionData = dict( getFolderLetterPopUpButton=dict( items=["A", "B", "C"] ) ) self.getFolderLetter = "A" self.getFolderNumber = 0 self.showGetFolder( messageText="This is the message text.", allowsMultipleSelection=True, directory=None, accessoryView=accessoryViewContents, descriptionData=accessoryViewDescriptionData, callback=self.showGetFolderResultCallback ) def getFolderLetterPopUpButtonCallback(self, sender): i = sender.get() self.getFolderLetter = sender.getItems()[i] def getFolderNumberRadioButtonsCallback(self, sender): self.getFolderNumber = sender.get() def showGetFolderResultCallback(self, result): print(f"Path: {result} Letter: {self.getFolderLetter} Number: {self.getFolderNumber}") DemoController()
- showGetFile(callback, fileTypes=[], allowsMultipleSelection=False, messageText=None, directory=None, accessoryView=None, descriptionData={})
import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showGetFile) @showGetFileButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showGetFileButtonCallback(None) def showGetFileButtonCallback(self, sender): accessoryViewContents = """ = TwoColumnForm : Letter: (A ...) @getFileLetterPopUpButton : Number: (X) 0 @getFileNumberRadioButtons ( ) 1 ( ) 2 """ accessoryViewDescriptionData = dict( getFileLetterPopUpButton=dict( items=["A", "B", "C"] ) ) self.getFileLetter = "A" self.getFileNumber = 0 self.showGetFile( messageText="This is the message text.", fileTypes=["txt", "py"], allowsMultipleSelection=True, directory=None, accessoryView=accessoryViewContents, descriptionData=accessoryViewDescriptionData, callback=self.showGetFileResultCallback ) def getFileLetterPopUpButtonCallback(self, sender): i = sender.get() self.getFileLetter = sender.getItems()[i] def getFileNumberRadioButtonsCallback(self, sender): self.getFileNumber = sender.get() def showGetFileResultCallback(self, result): print(f"Path: {result} Letter: {self.getFileLetter} Number: {self.getFileNumber}") DemoController()
- showPutFile(callback, fileTypes=[], fileName=None, directory=None, accessoryView=None, descriptionData={}, messageText=None, canCreateDirectories=True)
import ezui class DemoController(ezui.WindowController): def build(self): content = """ (showPutFile) @showPutFileButton """ self.w = ezui.EZWindow( title="Demo", size=("auto"), content=content, controller=self ) def started(self): self.w.open() self.showPutFileButtonCallback(None) def showPutFileButtonCallback(self, sender): accessoryViewContents = """ = TwoColumnForm : Letter: (A ...) @putFileLetterPopUpButton : Number: (X) 0 @putFileNumberRadioButtons ( ) 1 ( ) 2 """ accessoryViewDescriptionData = dict( putFileLetterPopUpButton=dict( items=["A", "B", "C"] ) ) self.putFileLetter = "A" self.putFileNumber = 0 self.showPutFile( messageText="This is the message text.", fileTypes=["abc", "xyz"], fileName="Demo.abc", canCreateDirectories=True, directory=None, accessoryView=accessoryViewContents, descriptionData=accessoryViewDescriptionData, callback=self.showPutFileResultCallback ) def putFileLetterPopUpButtonCallback(self, sender): i = sender.get() self.putFileLetter = sender.getItems()[i] def putFileNumberRadioButtonsCallback(self, sender): self.putFileNumber = sender.get() def showPutFileResultCallback(self, result): print(f"Path: {result} Letter: {self.putFileLetter} Number: {self.putFileNumber}") DemoController()
- getWindow()
Get the window this controller controls.
Subclasses must override this if their window is not located at
self.w.
- build()
This will be called when the controller is initialized. Subclasses should override this to build the window that this controller controls. The window must not be opened while this method is executing. Open the window in the
startedmethod.
- started()
This will be called after the build process is completed. Subclasses should override this to open the window that this controller controls and do any other work that can’t be completed in the
buildmethod.
- destroy()
This will be called when the window is closed. Subclasses may override to tear down anything necessary.
ContainerController
- class ezui.ContainerController(*args, **kwargs)
A container controller. This isn’t intended for use on its own. It primarily serves as a superclass for
GlyphEditorContainerControllerandInspectorItemContainerController.- addToParent(parent, position=(0, 0), width=None, height=None, identifier=None)
Add the container this controller controls to
parent.parentA Vanilla object capable of containing views.positionThe position of the container withinparent. For the time being, position must be expressed in Vanilla style coordinates. Optional.widthThe desired width of the container. Optional.heightThe desired height of the container. Optional.identifierA unique identifier for the container. This is currently only used by GlyphEditorContainerController. Optional.
- removeFromParent()
Remove the container from the parent.
- getContainer()
Get the container this controller controls.
Subclasses must override this if their window is not located at
self.v.
- build()
This will be called when the controller is initialized. Subclasses should override this to build the container that this controller controls. The container must not be added to the parent view while this method is executing. Do this in the
startedmethod.
- started()
This will be called after the build process is completed. Subclasses should override this to add the container that this controller controls to the parent view and do any other work that can’t be completed in the
buildmethod.
- destroy()
This will be called when the container is destroyed. Subclasses may override to tear down anything necessary.
GlyphEditorContainerController
- class ezui.GlyphEditorContainerController(*args, **kwargs)
A controller for containers displayed in the Glyph Editor.
class GlyphEditorTest(Subscriber, GlyphEditorContainerController): debug = True def build(self): contents = """ EZUI in glyph editor. (This is a button) @button ---X-------------- @slider (X) One @radioButtons ( ) Two ( ) Three |----------------| @table | | |----------------| """ descriptionData = dict( slider=dict( minValue=0, maxValue=100, value=75 ), table=dict( height=100, items=[ "this", "is", "a", "table" ] ) ) self.v = ezui.VerticalStack( contents=contents, descriptionData=descriptionData, controller=self ) def started(self): editor = self.getGlyphEditor() self.addToGlyphEditor( "com.typesupply.ezuiContainerControllerTest.GlyphEditor", position=(50, 50), width=150 ) def sliderCallback(self, sender): print("glyph editor sliderCallback", sender.get()) registerGlyphEditorSubscriber(GlyphEditorTest)
- addToGlyphEditor(identifier, position=(0, 0), width=None, height=None)
Add the container this controller controls to the glyph editor assigned to this
Subscriber.parentA Vanilla object capable of containing views.positionThe position of the container within the glyph editor. For the time being, position must be expressed in Vanilla style coordinates. Optional.widthThe desired width of the container. Optional.heightThe desired height of the container. Optional.identifierA unique identifier for the container.
InspectorItemContainerController
- class ezui.InspectorItemContainerController(*args, **kwargs)
A controller for Inspector items.
To control the initial appearance of your item, you may define a
inspectorItemDatadictionary in youtbuildmethod. If you need to override the default behavior, use these keys:titleThe desired title of the section in Inspector.indexThe index at which you want the item inserted into the Inspector. Default is last.insertBeforeThe title of the specific section in Inspector you would like your panel to precede. Default is last. This will overwriteindex.minSizeThe minimum size for the item.collapsedIf the item is initially collapsed.canResizeIf the item can be resized by the user.
You do not add the item to the Inspector directly. This will be handled automatically for you.
class InspectorTest(Subscriber, InspectorItemContainerController): debug = True def build(self): contents = """ EZUI in an inspector. view (This is a button) @button ---X-------------- @slider (X) One @radioButtons ( ) Two ( ) Three |----------------| @table | | |----------------| """ descriptionData = dict( slider=dict( minValue=0, maxValue=100, value=75 ), table=dict( height=100, items=[ "this", "is", "a", "table" ] ) ) self.v = ezui.VerticalStack( contents=contents, descriptionData=descriptionData, controller=self ) self.inspectorItemData = dict( title=Test, collapsed=False ) def sliderCallback(self, sender): print("inspector sliderCallback", sender.get()) registerRoboFontSubscriber(InspectorTest)